<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # nginx-push-stream-module 模塊 #### 1. 介紹 > A pure stream http push technology for your Nginx setup. > > Comet made easy and really scalable. > > Supports EventSource, WebSocket, Long Polling, and Forever Iframe. [nginx-push-stream-module](https://github.com/wandenberg/nginx-push-stream-module)是nginx的一個模塊,用它可以輕易實現websocket服務器。 以前我們實現websocket的服務器,不外乎兩種方式,第一種是嵌入到web進程中,成為web進程的一部分,只是以路由的方式提供服務,還有一種是單獨的進程,比如用puma來啟動包含actioncable的rails項目。 這兩種方式多多少少跟web進程都有些關系,嵌入型的就不用多說,就算是單獨的進程這種方式,也是用了另一種服務器去啟動。 現在我們來考慮另外一種方式,就是用完全獨立于web進程的服務器,比如,之前我們的web是用ruby寫的,可能會用puma或unicorn來啟動,現在我們可以用c++啟動websocket服務器,而web進程是通過http請求等方式來連接websocket服務器。 當然,這一篇文章,我們是用nginx來啟動一個websocket的服務器,nginx本身沒有這樣的功能,需要其中的一個模塊,就是本章介紹的`nginx-push-stream-module`。 現在我們先來跑一下流程,再來講述一下它的原理以及為什么能夠這樣做。 #### 2. 使用 首先得先安裝一下這個模塊。 ##### 2.1 安裝 安裝很簡單,跟之前的模塊安裝一模一樣的步驟,具體可以查看這篇文章[nginx之編譯第三方模塊(六)](http://www.rails365.net/articles/nginx-zhi-bian-yi-di-san-fang-mo-kuai-liu)。 現在來列出一下大概的流程。 ``` $ git clone https://github.com/wandenberg/nginx-push-stream-module.git # 進入到nginx源碼目錄,--add-module后面接nginx-push-stream-module的源碼目錄 $ ./configure --add-module=../nginx-push-stream-module # 編譯 $ make # 安裝 $ sudo make install # 結束老的nginx進程 $ sudo nginx -s quit # 開啟新的nginx進程 $ sudo nginx ``` 接著我們來使用這個模塊。 ##### 2.2 配置 在配置文件`nginx.conf`中添加下面這樣的內容: ``` http { push_stream_shared_memory_size 32M; server { location /channels-stats { # activate channels statistics mode for this location push_stream_channels_statistics; # query string based channel id push_stream_channels_path $arg_id; } location /pub { # activate publisher (admin) mode for this location push_stream_publisher admin; # query string based channel id push_stream_channels_path $arg_id; } location ~ /ws/(.*) { # activate websocket mode for this location push_stream_subscriber websocket; # positional channel path push_stream_channels_path $1; # message template push_stream_message_template "{\"id\":~id~,\"channel\":\"~channel~\",\"text\":\"~text~\"}"; push_stream_websocket_allow_publish on; # ping frequency push_stream_ping_message_interval 10s; } } } ``` ##### 2.3 原理 其中`push_stream_shared_memory_size`是添加在`http`下,其他的都在`server`下。 `push_stream_shared_memory_size`我就不詳說了,應該設置的是一個內存的容量,我對此細節并不了解,按照默認的就好了。 我們來講述一下`server`之下的三個`location`。 - /channels-stats - /pub - ~ /ws/(.\*) 第一個是關于websocket統計相關的東西,這個稍后再講。 另外兩個是關于發布訂閱的。 其中客戶端連接到服務器使用的是`~ /ws/(.*)`這個`location`,而服務器端向客戶端推送消息是使用`/pub`這個`location`。 至于客戶端與服務器端是如何交互的,我們可以回顧一下。 客戶端,比如瀏覽器,發送`new WebSocket`給websocket服務器,表示要建立websocket請求,這個過程表示的是訂閱,一直在等待服務器發送消息過來,一旦有消息過來,就會更改一些狀態,比如DOM更新等。這個過程,不止只有一個客戶端連接上服務器,可能有好多客戶端同時連接。假如現在有了業務變化,服務器需要向所有的客戶端推送消息,這個過程就是發布,廣播消息。通過什么廣播消息呢,這個機制可以自己實現,也可以用redis的pub/sub功能,比如,一旦客戶端連接上服務器,就會訂閱redis的一個channel,而發布的時候,就是往這個channel里推送消息,這樣,所有的客戶端都能接收到消息。 `nginx-push-stream-module`不需要redis的pub/sub,它是自己實現的。 ##### 2.4 測試 現在我們開始來測試一下這個應用。 還記得之前提到的`/channels-stats`這個`location`嗎?它是統計信息用的。 我們先來看下它的結果。 ``` $ curl -s -v 'http://localhost/channels-stats' ``` 輸出的內容主要是下面的json信息: ``` {"hostname": "macintoshdemacbook-air.local", "time": "2016-05-07T12:02:34", "channels": 0, "wildcard_channels": 0, "published_messages": 0, "stored_messages": 0, "messages_in_trash": 0, "channels_in_trash": 0, "subscribers": 0, "uptime": 19755, "by_worker": [ {"pid": "21117", "subscribers": 0, "uptime": 19755} ]} ``` 上面的信息包括主機名,時間,通道的個數,消息的個數等,我們先不管。 現在我們用瀏覽器建立一個連接到websocket服務器,也就是要請求`~ /ws/(.*)`這個`location`。 ``` ws = new WebSocket("ws://localhost/ws/ch1"); ws.onmessage = function(evt){console.log(evt.data);}; ``` 很簡單,使用`new WebSocket`建立一個websocket請求,地址為`ws://localhost/ws/ch1`。 `ch1`是通道的名稱,`push_stream_channels_path $1;`這一行配置指的就是它。 `onmessage`表示接收服務器端的消息,一旦有消息過來,就用`console.log`輸出來。 我們一直在關注著瀏覽器的輸出。 現在我們給客戶端推送一條消息,自然是使用`/pub`這個`location`。 ``` $ curl http://localhost/pub\?id\=ch1 -d "Some Text" {"channel": "ch1", "published_messages": 1, "stored_messages": 0, "subscribers": 1} ``` 使用的是curl這個命令,`ch1`表示的是通道名,它可以以參數的形式來指定,這樣就會靈活很多,不同類型的連接可以用不同的通道名。 果然瀏覽器輸出了信息了: ``` {"id":1,"channel":"ch1","text":"Some Text"} ``` `id`是消息的編號,默認從1開始,這個數字會自增,`channel`表示通道名,`text`是服務器端發送的信息。 輸出的內容,跟`push_stream_message_template "{\"id\":~id~,\"channel\":\"~channel~\",\"text\":\"~text~\"}";`這里定義的模版有關。 果然是推送了什么內容就是輸出了什么內容。 現在我們來看看統計內容的輸出: ``` $ curl -s -v 'http://localhost/channels-stats' {"hostname": "macintoshdemacbook-air.local", "time": "2016-05-07T12:24:13", "channels": 1, "wildcard_channels": 0, "published_messages": 1, "stored_messages": 0, "messages_in_trash": 0, "channels_in_trash": 0, "subscribers": 1, "uptime": 21054, "by_worker": [ {"pid": "21117", "subscribers": 1, "uptime": 21054} ]} ``` 可以看到`"channels": 1`表示有一個通道,之前是沒有的,`"published_messages": 1`表示發布的消息也多了一條了。 我們可以發起多個`new WebSocket`或開多個瀏覽器進行測試,那樣可以觀看到更多的效果。 之前通過curl工具,向`/pub`這個`location`發送了http請求,這個就間接向客戶端發送數據,只是表現方式跟之前的不太一樣。 ##### 2.5 ruby 在實際的編程中,我們可以會用ruby應用結合nginx的`nginx-push-stream-module`這個模塊來做應用,總不至用curl這個工具,這個工具主要用于測試,我們現在試一下用ruby來代替curl。 開啟一個ruby的命令終端`irb`。 ``` require 'net/http' uri = URI("http://localhost/pub\?id\=ch1") http = Net::HTTP.new(uri.host, uri.port) req = Net::HTTP::Post.new(uri.to_s) req.body = 'Some Text' http.request(req) ``` 你會發現,效果是一樣的。 `nginx-push-stream-module`是個不錯的工具,如果靈活運用它,肯定有意想不到的好處。 完結。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看