首頁 >web前端 >js教程 >用三個和節點在VR中可視化Twitter流

用三個和節點在VR中可視化Twitter流

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌原創
2025-02-19 12:48:11241瀏覽

用三個和節點在VR中可視化Twitter流

Twitter是一隻美妙而豐富的野獸。我想將一些可視化的功能,三。及其VR功能與socket.io和節點結合在一起,以創建通過Twitter流生成的漂亮粒子世界。

>我以前已經討論過在SitePoint文章中開發虛擬現實網絡體驗的所有基礎知識,將VR帶到網絡上使用Google Cardboard和Thrive.js,因此,如果您是整個想法的新手,請先閱讀該一個,然後再閱讀一個,然後出現。後退。該演示使用相同的基礎。

>我們將要構建的演示將觀看現場Twitter流以獲取關鍵字。當一個人在觀看溪流時發推文時,它將帶來一個閃亮的顆粒的“塔”,代表了推文的時間。特別是該演示將尋找“披薩”一詞。你為什麼要披薩?我正在尋找一個不像“ Bieber”那樣頻繁提及的術語,而是“ Boxcar Racing Hyenas”更頻繁。簡而言之,最好的術語是相對頻繁的術語,在您正在觀看時會出現它們,但並不是那麼頻繁,以至於它們每秒幾百次。披薩是其中之一。

鑰匙要點

>利用node.js和socket.io創建一個可以處理和發射Twitter流數據的實時服務器,從而增強了VR可視化的交互性。 >
    集成了三個.js以構建一個3D VR環境,其中推文表示為唯一的粒子塔,根據推文長度的高度變化。
  • >通過設置最大粒子計數並在定義範圍內安排粒子塔來優化VR中的用戶體驗,以防止性能滯後。
  • >通過使用用戶配置文件顏色來自定義Tweet表示的視覺方面
  • >通過在Heroku等平台上部署節點服務器並使用Ngrok等隧道服務在各種設備上測試VR體驗,請確保廣泛的可訪問性和實時功能。
  • 演示代碼
  • 如果您渴望直接進入代碼並嘗試一下,則可以在GitHub上找到它。
>是否想在行動中嘗試?我在這里托管了一個跑步版本:VR Twitter World。

我們的服務器代碼

我們將首先查看我們的節點服務器代碼。它將顯示我們的Flat HTML,並且還可以作為socket.io服務器運行,該服務器將從Twitter中汲取數據流。

>

完整的服務器相對較短,看起來很短:

>我們的第一行使用Node Express Framework設置服務器。這是一個相當簡單的設置,正在吸引我們所有的依賴項,並為我們準備訪問服務器功能的應用變量。端口設置了我們希望服務器運行的哪個端口(process.env.port是服務器變量,某些託管設置(例如Heroku)將定義)。

<span>var express = require('express'),
</span>    app <span>= express(),
</span>    server <span>= require('http').createServer(app),
</span>    port <span>= process.env.PORT || 80,
</span>    io <span>= require('socket.io')(server),
</span>    config <span>= require('./config.json'),
</span>    <span>Twitter = require('node-tweet-stream'),
</span>    t <span>= new Twitter(config);
</span>
app<span>.get('/', function(request<span>, response</span>) {
</span>  response<span>.sendFile(__dirname + '/public/index.html');
</span><span>});
</span>
app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) {
</span>  res<span>.sendFile(__dirname + '/public/' + req.params[0]);
</span><span>});
</span>
app<span>.use(function(err<span>, req, res, next</span>) {
</span>  <span>console.error(err.stack);
</span>  res<span>.status(500).send('Something broke!');
</span><span>});
</span> 
server<span>.listen(port, function() {
</span>  <span>console.log('Listening on ' + port);
</span><span>});
</span>
t<span>.track('pizza');
</span>t<span>.on('tweet', function(tweet){
</span>  <span>console.log('Roger that. Tweets incoming!');
</span>  <span>console.log(tweet);
</span>
  io<span>.emit('tweet', tweet);
</span><span>});
</span>
t<span>.on('error', function (err) {
</span>  <span>console.log('Brace yourself! We are goin doooowwwwwwnnnnnnnn! ', err);
</span><span>});</span>
然後,我們設置IO變量,同時啟動我們的socket.io服務器功能,將其附加到我們上面設置的Express Server上:>

>設置Twitter訪問
<span>var express = require('express'),
</span>    app <span>= express(),
</span>    server <span>= require('http').createServer(app),
</span>    port <span>= process.env.PORT || 80,</span>

配置變量是將應用程序的Twitter身份驗證鍵和訪問令牌保留在自己的文件中的好方法。為了實時查看Twitter流,我們將使用一個名為Node-tweet-stream的NPM模塊,該模塊提供我們需要的所有功能。我們將Twitter訪問的對象和所有關聯功能分配給t變量,並傳遞我們的配置JSON,以證明我們可以訪問它。

>

io <span>= require('socket.io')(server),</span>
如果您沒有任何訪問Twitter API的Twitter鍵,請不要擔心!您只需要在Twitter上註冊一個應用程序即可。前往Twitter應用程序管理頁面,使用您的Twitter憑據登錄,然後單擊“創建新應用”。

>擁有應用程序後,您可以通過單擊將顯示在應用程序管理頁面上的“鍵和訪問令牌”鏈接來獲取鍵和訪問令牌。如果找不到它,它將在以下網址:https://apps.twitter.com/app/0000000/keys(用您的應用程序ID替換0000000)。

然後,在與index.html相同的級別上創建一個名為config.json的文件。在其中,使用您自己的應用程序的值添加以下內容:

其他服務器基礎知識
config <span>= require('./config.json'),
</span><span>Twitter = require('node-tweet-stream'),
</span>t <span>= new Twitter(config),</span>

>在我們的index.js文件中,我們將呼叫設置為服務器的根,以供load /public/index.html:

>我們還可以在服務器上的公共目錄中提供任何其他靜態文件:>
<span>{
</span>  <span>"consumer_key": "YOURKEY",
</span>  <span>"consumer_secret": "YOURKEYSECRET",
</span>  <span>"token": "YOURTOKEN",
</span>  <span>"token_secret": "YOURTOKENSECRET"
</span><span>}</span>

如果我們確實有錯誤,我們會在服務器的控制台中記錄該錯誤,然後返回500錯誤:

app<span>.get('/', function(request<span>, response</span>) {
</span>  response<span>.sendFile(__dirname + '/public/index.html');
</span><span>});</span>

以下幾行啟動我們的服務器運行,並以上面的所有設置運行。

>
app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) {
</span>  res<span>.sendFile(__dirname + '/public/' + req.params[0]);
</span><span>});</span>

>檢索我們的實時Twitter流

app<span>.use(function(err<span>, req, res, next</span>) {
</span>  <span>console.error(err.stack);
</span>  res<span>.status(500).send('Something broke!');
</span><span>});</span>
>最後,我們設置了特定於Twitter的服務器功能。我們使用track()函數來指定我們要在不斷擴展的Twitter內容流中跟踪哪個關鍵字。

然後,我們設置了一個回調函數,以便任何時候運行節點 - tweet-stream模塊,都以該關鍵字顯示一條推文。如果看到了一個,我們將其記錄在服務器的控制台日誌中(這是可選的,可以在您願意的情況下刪除),然後將其作為socket.io事件發出到任何連接的客戶端。

>如果我們的Twitter API出於任何原因有錯誤,則將登錄到我們的服務器日誌:>
server<span>.listen(port, function() {
</span>  <span>console.log('Listening on ' + port);
</span><span>});</span>

>與所有節點應用一樣,我們的所有服務器依賴性和詳細信息都存儲在package.json中。如果您是node.js的新手,則可能需要對所有內容的含義進行一些閱讀:package.json。

我們的前端代碼

>我們的前端代碼以Google Cardboard和Thrim.js文章的“ Bringing VR到Web”的相同設置開頭 - 我們通過立體鏡面效果顯示的三個.js場景,使我們的場景成為VR視圖。為了保持這一簡短而甜美,我不會涵蓋與該文章以前的演示相同的位。如果您不確定我在這裡沒有解釋的任何內容,請查看以前的文章以獲取信息。

>設置socket.io

與以前的基礎相比,我們將添加的唯一新JS文件是我們的socket.io javascript文件。這是一個簡單的襯裡:

為了從socket.io訪問功能,我們需要的只是將該功能分配給io變量,因為您會在我們的index.html文件中看到一些進一步的功能:
<span>var express = require('express'),
</span>    app <span>= express(),
</span>    server <span>= require('http').createServer(app),
</span>    port <span>= process.env.PORT || 80,
</span>    io <span>= require('socket.io')(server),
</span>    config <span>= require('./config.json'),
</span>    <span>Twitter = require('node-tweet-stream'),
</span>    t <span>= new Twitter(config);
</span>
app<span>.get('/', function(request<span>, response</span>) {
</span>  response<span>.sendFile(__dirname + '/public/index.html');
</span><span>});
</span>
app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) {
</span>  res<span>.sendFile(__dirname + '/public/' + req.params[0]);
</span><span>});
</span>
app<span>.use(function(err<span>, req, res, next</span>) {
</span>  <span>console.error(err.stack);
</span>  res<span>.status(500).send('Something broke!');
</span><span>});
</span> 
server<span>.listen(port, function() {
</span>  <span>console.log('Listening on ' + port);
</span><span>});
</span>
t<span>.track('pizza');
</span>t<span>.on('tweet', function(tweet){
</span>  <span>console.log('Roger that. Tweets incoming!');
</span>  <span>console.log(tweet);
</span>
  io<span>.emit('tweet', tweet);
</span><span>});
</span>
t<span>.on('error', function (err) {
</span>  <span>console.log('Brace yourself! We are goin doooowwwwwwnnnnnnnn! ', err);
</span><span>});</span>
>

準備我們的塔
<span>var express = require('express'),
</span>    app <span>= express(),
</span>    server <span>= require('http').createServer(app),
</span>    port <span>= process.env.PORT || 80,</span>
然後,我們為“塔”設置變量(基本上是代表推文的垂直粒子集)。我們所有的塔都存儲在一個稱為TweetTowers的三個對像中。這是一個容器對象,可讓我們跟踪所有塔:

明顯和特定材料是我們的變量,它將代表我們的顆粒的外觀:

MaxtowerCount是我們想在場景中可見的最大塔樓數量 - 如果設定太高,我們可能會獲得懶惰的體驗。我將其設置為6000,因為這將最大粒子設置為大約一百萬。我認為一個合理的數字!

>
io <span>= require('socket.io')(server),</span>
config <span>= require('./config.json'),
</span><span>Twitter = require('node-tweet-stream'),
</span>t <span>= new Twitter(config),</span>
>範圍是我們希望將這些塔放置在觀眾周圍的區域的大小。這些塔將被放置在現場的隨機位置,因此這將限制了它們的分開。我發現,與用戶更接近他們,這是一個更好的體驗。如果他們遠離用戶,看來沒有那麼多(儘管有成千上萬的粒子!)。我將其設置為100:

<span>{
</span>  <span>"consumer_key": "YOURKEY",
</span>  <span>"consumer_secret": "YOURKEYSECRET",
</span>  <span>"token": "YOURTOKEN",
</span>  <span>"token_secret": "YOURTOKENSECRET"
</span><span>}</span>
我們的init函數

>在我們的init()函數中沒有太多新事物。它主要設置了我們的VR攝像機,並按照上一篇文章所述進行控制。新的位在末尾。
app<span>.get('/', function(request<span>, response</span>) {
</span>  response<span>.sendFile(__dirname + '/public/index.html');
</span><span>});</span>

>我們將明顯的圖像定義為一個稱為粒子new.png的png,我們在公共文件夾中具有:

>我們通過將我們的TweetTowers容器添加到我們的場景中來完成INIT()函數。在我們的場景中,我們不必擔心將任何塔直接添加到場景中,我們只會將它們直接添加到我們的TweetTowers對像中。

對推文做出反應
app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) {
</span>  res<span>.sendFile(__dirname + '/public/' + req.params[0]);
</span><span>});</span>

>您會記得,一旦我們的服務器找到了通過Twitter的Tweet通過我們的“披薩”流式傳輸的推文,它就會發出一個稱為“ Tweet”的事件。我們的客戶端JavaScript現在將注意該事件並響應:

<span>var express = require('express'),
</span>    app <span>= express(),
</span>    server <span>= require('http').createServer(app),
</span>    port <span>= process.env.PORT || 80,
</span>    io <span>= require('socket.io')(server),
</span>    config <span>= require('./config.json'),
</span>    <span>Twitter = require('node-tweet-stream'),
</span>    t <span>= new Twitter(config);
</span>
app<span>.get('/', function(request<span>, response</span>) {
</span>  response<span>.sendFile(__dirname + '/public/index.html');
</span><span>});
</span>
app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) {
</span>  res<span>.sendFile(__dirname + '/public/' + req.params[0]);
</span><span>});
</span>
app<span>.use(function(err<span>, req, res, next</span>) {
</span>  <span>console.error(err.stack);
</span>  res<span>.status(500).send('Something broke!');
</span><span>});
</span> 
server<span>.listen(port, function() {
</span>  <span>console.log('Listening on ' + port);
</span><span>});
</span>
t<span>.track('pizza');
</span>t<span>.on('tweet', function(tweet){
</span>  <span>console.log('Roger that. Tweets incoming!');
</span>  <span>console.log(tweet);
</span>
  io<span>.emit('tweet', tweet);
</span><span>});
</span>
t<span>.on('error', function (err) {
</span>  <span>console.log('Brace yourself! We are goin doooowwwwwwnnnnnnnn! ', err);
</span><span>});</span>

響應代碼是對稱為generateTower()函數的調用,該函數將在我們的場景中添加塔,代表該推文。我們將其傳遞給四個值:

<span>var express = require('express'),
</span>    app <span>= express(),
</span>    server <span>= require('http').createServer(app),
</span>    port <span>= process.env.PORT || 80,</span>
  • >顏色是我們粒子的顏色。我們傳遞了用戶個人資料背景的顏色。這使我們能夠顯示出不同的顏色,以代表有關披薩的不同飢餓的用戶。 >
  • 開始座位是放置塔的地方。我們希望將它們放在我們周圍,因此我們將它們放在X和Z軸上的上方範圍變量之間(應在-100至100之間)。如果我們將它們隨機放置在Y上,它們將從地面更高和較低的不同級別開始,而不是像建築物一樣排列。我們絕對不想要它,因此我們確保它們都放置在0的位置。 getRandomarBitrary()是兩個值之間的簡單隨機數生成器。
  • 速度定義了我們的粒子最終放置的距離(或塔架上塔的速度上升的速度)。
  • 大小是我們塔高多少顆粒。假設最大Twitter長度為140個字符。
  • 顯示塔
>我們的generateTeTower()函數本身首先定義高層變量。這是一個三個幾何對象,它將包含塔中我們所有顆粒的位置。將跟踪的所有點保持在一個幾何對像中可以幫助保持處理時間的降低,因為三個。 JS只需要跟踪每個塔對象及其點,而不是一系列獨立的粒子。在代碼的稍後,我們將提供幾何形狀,以將這些點解釋到我們的粒子中的三個。

然後,我們設置了一個稱為顆粒的JavaScript對象,該對象存儲了我們的粒子將在塔中啟動和完成的位置,以及它們的相距多遠(我們之前通過的值):

>

> CurrentCoords變量跟踪塔中粒子的最後位置。我們將其初始化為0,0,0。較早的功能調用將放置將放置塔的起點座。如果我們沒有來自函數調用的任何啟動坐標,我們將它們初始化為與CurrentCoord相同:
io <span>= require('socket.io')(server),</span>

然後,我們迭代塔的大小以創建每個粒子。我們設置了當前的坐標,以使y的速度值乘以i。我們的x和z值僅在向上移動時就保持著起始位置。

config <span>= require('./config.json'),
</span><span>Twitter = require('node-tweet-stream'),
</span>t <span>= new Twitter(config),</span>
>在為該粒子定義的那些坐標中,我們將粒子的位置連接為高層測定對像中的頂點:

<span>var express = require('express'),
</span>    app <span>= express(),
</span>    server <span>= require('http').createServer(app),
</span>    port <span>= process.env.PORT || 80,
</span>    io <span>= require('socket.io')(server),
</span>    config <span>= require('./config.json'),
</span>    <span>Twitter = require('node-tweet-stream'),
</span>    t <span>= new Twitter(config);
</span>
app<span>.get('/', function(request<span>, response</span>) {
</span>  response<span>.sendFile(__dirname + '/public/index.html');
</span><span>});
</span>
app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) {
</span>  res<span>.sendFile(__dirname + '/public/' + req.params[0]);
</span><span>});
</span>
app<span>.use(function(err<span>, req, res, next</span>) {
</span>  <span>console.error(err.stack);
</span>  res<span>.status(500).send('Something broke!');
</span><span>});
</span> 
server<span>.listen(port, function() {
</span>  <span>console.log('Listening on ' + port);
</span><span>});
</span>
t<span>.track('pizza');
</span>t<span>.on('tweet', function(tweet){
</span>  <span>console.log('Roger that. Tweets incoming!');
</span>  <span>console.log(tweet);
</span>
  io<span>.emit('tweet', tweet);
</span><span>});
</span>
t<span>.on('error', function (err) {
</span>  <span>console.log('Brace yourself! We are goin doooowwwwwwnnnnnnnn! ', err);
</span><span>});</span>
確保我們對粒子的定位的設置的設置正確。接下來,我們定義該塔中的顆粒在顆粒變量中的外觀。我們的粒子將被放置在三個點雲對像中,因此將其造型,我們將使用三個coptcloudmaterial材料:>

<span>var express = require('express'),
</span>    app <span>= express(),
</span>    server <span>= require('http').createServer(app),
</span>    port <span>= process.env.PORT || 80,</span>
MAP定義了我們將用於粒子的圖像,我們通過了前面定義的特定時間表。
    顏色以我們希望粒子為顏色的顏色傳遞(默認為triph.js中的0xffffff)。
  • 混合設置了粒子如何融入場景的方式。 three.additive -glighend在其後面的紋理上添加了紋理的顏色。
  • 透明確保可以進行混合,因為它需要一定的透明度工作。 >
  • 大小是我們粒子的大小。
  • 最後,我們在塔的變量中定義了塔的點雲。我們傳遞包含希望每個粒子出現的點的幾何形狀,以及上面為它們定義的材料。
  • >我們將該塔添加到我們的TweetTowers Collection對像中,然後檢查以查看現場有多少塔。如果我們的塔超過允許的塔,我們將隱藏最古老的塔,以減少設備上的負載。如果您有任何性能問題,那麼如果您減少MaxtowerCount!
  • 運行我們的代碼
>要在本地運行此演示,您需要安裝節點,並且需要運行通常的命令。安裝項目的所有依賴項:

然後運行它:
io <span>= require('socket.io')(server),</span>

為了在智能手機上進行測試,您要么需要確保智能手機在同一本地網絡上並找到計算機的IP地址,要么使用Ngrok等隧道服務(我介紹瞭如何在文章中使用Ngrok從任何地方訪問本地主機)

>
config <span>= require('./config.json'),
</span><span>Twitter = require('node-tweet-stream'),
</span>t <span>= new Twitter(config),</span>
>您也可以在某個地方託管節點服務器。我個人使用了Heroku,但這完全是個人的偏好。

>

>將服務器設置在某個地方並運行後,打開Chrome以供移動設備訪問!戴上您的Google紙板或其他類似耳機,您應該看到一種經歷,如果您抬頭看,則在半分鐘左右後看起來像這樣:

<span>{
</span>  <span>"consumer_key": "YOURKEY",
</span>  <span>"consumer_secret": "YOURKEYSECRET",
</span>  <span>"token": "YOURTOKEN",
</span>  <span>"token_secret": "YOURTOKENSECRET"
</span><span>}</span>
結論

>這應該為您提供了使用Node,socket.io和Trix.js創建啟用3D Web API的虛擬現實可視化的良好概述。可以進一步開發演示本身,增加更多的關鍵字,過濾器,使其與更多粒子等等更光滑。有很多潛力!隨時出去那裡,嘗試通過此演示來獲得自己的出色體驗!
app<span>.get('/', function(request<span>, response</span>) {
</span>  response<span>.sendFile(__dirname + '/public/index.html');
</span><span>});</span>

>我還在Sitepoint上還有其他使用類似概念的演示,而是將它們帶入了增強的現實體驗。如果您有興趣,請使用JavaScript和Google Cardboard過濾現實,探索從您的智能手機中攝取的相機並將過濾器添加到它的相機,並在瀏覽器中增強現實,awe.js探索一路探索並通過將元素擴大到您的視野中。三分和敬畏的強大組合!

>

如果您確實承擔了本文中從演示中進行自己的VR可視化的挑戰(或將其與提到的AR示例中的元素結合在一起),請在評論中留下註釋或與之聯繫我在Twitter上(@thatpatrickguy),我會拿出頭戴式耳機,看看!

經常詢問的問題(常見問題解答),以在VR中可視化twitter流的三個.js和node

>

我如何為網站設置Twitter?

>為網站設置Twitter涉及幾個步驟。首先,您需要在Twitter開發人員的網站上創建一個Twitter應用程序。創建應用程序後,您將收到一組鍵和令牌。這些用於用Twitter來驗證您的應用程序。然後,您需要在網站上安裝Twitter JavaScript API。此API允許您的網站與Twitter進行交互,從而啟用了諸如Tweet按鈕和嵌入式推文之類的功能。

什麼是three.js,它如何工作?

three.js是跨瀏覽器用於在Web瀏覽器中創建和顯示動畫3D計算機圖形的JavaScript庫。它使用WebGL渲染圖形。該庫提供了一組對象和方法,使創建複雜的3D場景變得更容易,包括相機,燈光,材料和幾何形狀。

>

如何在node.js上使用three.js?

>要在node.js上使用trix.js,您需要使用node.js package manager安裝“三”軟件包。安裝後,您可以在node.js腳本中需要“三個”模塊。然後,您可以使用三個.js api創建3D圖形。

>如何在VR?

​​

中可視化Twitter流中的Twitter流>在VR中可視化的Twitter流涉及幾個步驟。首先,您需要使用Twitter API設置Twitter流。這涉及創建一個Twitter應用程序並使用您的Twitter帳戶對其進行認證。設置流後,您可以使用Trix.js創建推文的3D可視化。這涉及創建一個3D場景,添加對像以表示推文,並隨著新推文到達時實時更新場景。 >

three.js是一個高級庫,為創建3D圖形提供了簡單的API。它抽象了直接與WebGL合作的許多複雜性,從而更容易創建複雜的3D場景。其他庫可能會提供對WebGL的更低級訪問權限,但需要更深入地了解3D圖形編程。 Twitter流,出於多種原因可能發生錯誤,例如網絡問題或不正確的身份驗證憑證。 Twitter API提供的錯誤消息可以幫助您診斷和解決這些問題。處理代碼中的這些錯誤很重要,以確保您的應用程序繼續順利運行。

>如何優化我的three.js應用程序的性能?

>優化三。 js應用程序涉及多種技術。其中包括降低3D型號的複雜性,優化紋理,並最大程度地減少抽獎呼叫的數量。您還可以使用諸如Three.js Inspertor之類的工具來分析應用程序的性能並確定瓶頸。

>

>我如何自定義在VR?

​​

中的Twitter流的外觀,您可以自定義通過修改表示推文的3D對象的屬性,在VR中的Twitter流的外觀。這包括顏色,紋理和大小等屬性。您還可以使用不同類型的燈光和相機來改變場景的整體外觀。 VR中的流涉及使用事件偵聽器檢測用戶操作,例如點擊或觸摸。然後,您可以根據這些操作更新3D場景。例如,您可以允許用戶單擊推文,或使用觸摸手勢瀏覽場景。

>如何將我的三個.js應用程序部署到網絡? Web上的三分應用程序涉及包裝您的應用程序文件並將其上傳到Web服務器。您可以使用WebPack之類的工具來捆綁JavaScript文件,以及諸如GitHub頁面或Netlify之類的服務來託管您的應用程序。部署後,使用Web瀏覽器的任何人都可以訪問您的應用程序。

>

以上是用三個和節點在VR中可視化Twitter流的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn