国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

[Websocket]如何向指定終端發(fā)送消息?

火紅的鯉魚

我啟動(dòng)了一個(gè)websocket服務(wù)(websocket協(xié)議),然后打開了瀏覽器,打開了兩個(gè)瀏覽器標(biāo)簽頁(yè)與其建立連接(通過(guò)js原生的Websocket對(duì)象),然而,實(shí)際上我發(fā)現(xiàn)connections只有一個(gè),這導(dǎo)致我無(wú)法向指定的標(biāo)簽頁(yè)發(fā)送信息。
請(qǐng)問(wèn),如何向指定的客戶端發(fā)送信息?
?----------------------------分割線----------------------------
?
我是按照如下方式發(fā)現(xiàn)多個(gè)標(biāo)簽頁(yè)用的是同一個(gè)connection的。
首先,在join或login時(shí)打印workerId和$connection->id拼成的字符串(logEvent是我自定義的日志輸出函數(shù))

[attach]1866[/attach]

[attach]1867[/attach]
?
然后,打開兩個(gè)瀏覽器標(biāo)簽頁(yè)各自建立連接

[attach]1870[/attach]

[attach]1871[/attach]

?
最后,查看服務(wù)端日志信息
?Workerman start in DEBUG mode
------------------------------------------- WORKERMAN --------------------------------------------
Workerman version:3.5.18 PHP version:7.2.8
-------------------------------------------- WORKERS ---------------------------------------------
proto user worker listen processes status
tcp www-data none websocket://0.0.0.0:2346 4

Press Ctrl+C to stop. Start success.
new connection is coming...172.18.0.1
2019-04-01 13:43:08:
2019-04-01 13:43:08:
2019-04-01 13:43:08:
2019-04-01 13:43:08:
2019-04-01 13:43:08:
-----join over

2019-04-01 13:43:08:
2019-04-01 13:43:08:
2019-04-01 13:43:08:
2019-04-01 13:43:08:
2019-04-01 13:43:08:
2019-04-01 13:43:08:
-----login over

new connection is coming...172.18.0.1
2019-04-01 13:43:13:
2019-04-01 13:43:13:
2019-04-01 13:43:13:
2019-04-01 13:43:13:
-----join over

2019-04-01 13:43:14:
2019-04-01 13:43:14:
2019-04-01 13:43:14:
2019-04-01 13:43:14:
2019-04-01 13:43:14:
2019-04-01 13:43:14:
-----login over

可以看到,兩次連接,經(jīng)過(guò)了兩輪join/login,但是每次的workerId_$connection->id組合都是一致的,都是0000000045562dda0000000048257f4c_1但是官方文檔上說(shuō),http://doc.workerman.net/tcp-connection.html,所以,是我使用姿勢(shì)不對(duì)么?請(qǐng)指教。

7356 1 0
1個(gè)回答

phpcreeper

使用姿勢(shì)不對(duì):
不能使用?workerId 【用于區(qū)分不同的worker實(shí)例】, 至少使用 $worker->id??是正確的【用于區(qū)分同一個(gè)worker實(shí)例的不同進(jìn)程】。

  • 火紅的鯉魚 2019-04-01

    但是我用了$worker->id拿到worker的id之后,怎么獲得那個(gè)worker的實(shí)例呢?我之前是用Worker::getAllWorkers()獲取了worker數(shù)組,然后發(fā)現(xiàn)它的鍵其實(shí)是workerId。

  • 火紅的鯉魚 2019-04-01

    其實(shí)我是想讓標(biāo)簽頁(yè)1給標(biāo)簽頁(yè)2發(fā)送一個(gè)websocket消息,所以我就得獲取用于標(biāo)簽頁(yè)2的那個(gè)$connection實(shí)例。

  • phpcreeper 2019-04-01

    兩個(gè)頁(yè)面發(fā)起的websocket連接分別是兩個(gè)不同的連接對(duì)象,而 $connection->worker 就是獲得當(dāng)前連接所屬的worker實(shí)例,所謂的兩個(gè)標(biāo)簽頁(yè)要進(jìn)行互相推送消息,就是不同的連接對(duì)象就行通信的過(guò)程,所以我們只要確定出不同的唯一的連接對(duì)象uid,比如可以這樣使用:
    $uid = $conneciton->worker->id . $connection->id;

    另外注意: 單進(jìn)程和多進(jìn)程的通信手段是不一樣的,具體怎么玩手冊(cè)上都有特別說(shuō)明。

  • 火紅的鯉魚 2019-04-03

    多謝,我找到這個(gè)問(wèn)題的解決方案了,在這個(gè)頁(yè)面上:http://doc.workerman.net/components/channel-examples.html

    總結(jié)一下,在workerman里面,由于每個(gè)connection保持一個(gè)連接,所以如果你要針對(duì)某個(gè)客戶端發(fā)送消息的話,實(shí)際上是要通過(guò)那個(gè)特定的connection去發(fā)送這個(gè)消息,而connection又被worker持有,所以你得先找到那個(gè)worker,再找到那個(gè)connection,然后才能發(fā)送消息。

    要調(diào)動(dòng)某個(gè)特定的worker,需要做進(jìn)程間通信,因?yàn)槟悴荒艽_定當(dāng)前負(fù)責(zé)處理消息任務(wù)的那個(gè)worker就是持有那個(gè)connection的worker。workerman有一個(gè)ChannelServer組件,就是在上面鏈接的那個(gè)頁(yè)面中,利用這個(gè)ChannelServer可以做到進(jìn)程間通信,具體流程就是:

    1、廣播指令到達(dá)
    2、向監(jiān)聽(tīng)了指定worker->id的ChannelClient發(fā)送消息(這里為什么要監(jiān)聽(tīng)worker->id而不是別的,因?yàn)檫@樣可以節(jié)省好多流量和cpu操作,要不然,你的每個(gè)worker都要響應(yīng)一下這個(gè)消息事件來(lái)查看這個(gè)消息是不是發(fā)給自己的)
    3、根據(jù)發(fā)送的消息數(shù)據(jù)來(lái)確定由哪個(gè)connection處理該消息
    4、調(diào)用指定connection的send方法(完成廣播,其實(shí)廣播就是循環(huán)調(diào)用一批connection)

    ——————————————分割線————————————————

    再說(shuō)一下我的誤區(qū)。

    之前查看文檔說(shuō),每個(gè)連接都由一個(gè)connection保持,然后我在發(fā)送廣播的時(shí)候,首先冒出的第一個(gè)想法就是,那我得先找到那個(gè)connection(這個(gè)想法沒(méi)錯(cuò)),然后我發(fā)現(xiàn)是worker持有connection,然后就得找到worker,才能找到connection(到這里,想法也沒(méi)錯(cuò))。

    然后由于服務(wù)是多進(jìn)程的,不能確定是被哪個(gè)worker處理了,所以,我的想法是建立一個(gè)數(shù)據(jù)共享機(jī)制,讓無(wú)論在哪個(gè)worker中都可以獲得某個(gè)指定的worker實(shí)例(這里開始有問(wèn)題了),所以我使用了GlobalData組件,不管哪個(gè)worker收到消息,都把自身的id在這個(gè)共享庫(kù)中注冊(cè)一下,然后當(dāng)廣播消息到達(dá)時(shí),我就去這個(gè)共享庫(kù)中找那個(gè)worker,然后找到那個(gè)worker中的那個(gè)特定的connection。

    表面上看,這樣做貌似沒(méi)毛病,但是有個(gè)很大的錯(cuò)誤,就是,就算我把所有worker的id都注冊(cè)到了數(shù)據(jù)共享庫(kù)中,我也無(wú)法直接在某個(gè)進(jìn)程worker中操作別的進(jìn)程worker,因?yàn)檫M(jìn)程之間是互相隔離的-_-!!。

    所以就需要進(jìn)程間通信了,所以就需要ChannerServer。

    ——————————————分割線————————————————

    按照我那種錯(cuò)誤的做法,實(shí)際表現(xiàn)出來(lái)的結(jié)果是,數(shù)據(jù)共享庫(kù)中一直只保存了一個(gè)wokerId+connection->id組合。

年代過(guò)于久遠(yuǎn),無(wú)法發(fā)表回答
??