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

如何在php后端及時推送消息給客戶端

eriodesign

walkor大神,目前需求是這樣的:

有一群商家在后臺網(wǎng)頁處理批量導入產(chǎn)品 -》 服務器接受請求 -》 開始foreach一個一個處理導入請求;

我現(xiàn)在想每成功導入一個就推送到前臺顯示已經(jīng)導入成功,直到全部導入自動結束推送。

看了聊天室代碼,消息推送都是靠前端js+event.php,我想直接在php里面不需要onMessage觸發(fā).

我從下午看到現(xiàn)在文檔,也看了很多問答,依然非常糊涂,不奢望給整段代碼,但是希望walkor大神給點思路。

96739 41 21
41個回答

walkor 打賞

后端代碼
push.php

<?php
use Workerman\Worker;
require_once './Workerman/Autoloader.php';
// 初始化一個worker容器,監(jiān)聽1234端口
global $worker;
$worker = new Worker('websocket://0.0.0.0:1234');
// 這里進程數(shù)必須設置為1
$worker->count = 1;
// worker進程啟動后建立一個內(nèi)部通訊端口
$worker->onWorkerStart = function($worker)
{
    // 開啟一個內(nèi)部端口,方便內(nèi)部系統(tǒng)推送數(shù)據(jù),Text協(xié)議格式 文本+換行符
    $inner_text_worker = new Worker('Text://0.0.0.0:5678');
    $inner_text_worker->onMessage = function($connection, $buffer)
    {
        global $worker;
        // $data數(shù)組格式,里面有uid,表示向那個uid的頁面推送數(shù)據(jù)
        $data = json_decode($buffer, true);
        $uid = $data['uid'];
        // 通過workerman,向uid的頁面推送數(shù)據(jù)
        $ret = sendMessageByUid($uid, $data['percent']);
        // 返回推送結果
        $connection->send($ret ? 'ok' : "uid $uid not online");
    };
    $inner_text_worker->listen();
};
// 新增加一個屬性,用來保存uid到connection的映射
$worker->uidConnections = array();
// 當有客戶端發(fā)來消息時執(zhí)行的回調(diào)函數(shù)
$worker->onMessage = function($connection, $data)use($worker)
{
    // 判斷當前客戶端是否已經(jīng)驗證,既是否設置了uid
    if(!isset($connection->uid))
    {
        // 沒驗證的話把第一個包當做uid(這里為了方便演示,沒做真正的驗證)
        $connection->uid = $data;
        /* 保存uid到connection的映射,這樣可以方便的通過uid查找connection,
         * 實現(xiàn)針對特定uid推送數(shù)據(jù)
         */
        $worker->uidConnections[$connection->uid] = $connection;
        return;
    }
};
// 當有客戶端連接斷開時
$worker->onClose = function($connection)use($worker)
{
    global $worker;
    if(isset($connection->uid))
    {
        // 連接斷開時刪除映射
        unset($worker->uidConnections[$connection->uid]);
    }
};
// 向所有驗證的用戶推送數(shù)據(jù)
function broadcast($message)
{
    global $worker;
    foreach($worker->uidConnections as $connection)
    {
        $connection->send($message);
    }
}
// 針對uid推送數(shù)據(jù)
function sendMessageByUid($uid, $message)
{
    global $worker;
    if(isset($worker->uidConnections[$uid]))
    {
        $connection = $worker->uidConnections[$uid];
        $connection->send($message);
        return true;
    }
    return false;
}
// 運行所有的worker(其實當前只定義了一個)
Worker::runAll();

啟動后端服務
php push.php start -d

前端接收推送的js代碼

var ws = new WebSocket('ws://127.0.0.1:1234');
ws.onopen = function(){
    var uid = 'uid1';
    ws.send(uid);
};
ws.onmessage = function(e){
    alert(e.data);
};

后端推送消息的代碼

// 建立socket連接到內(nèi)部推送端口
$client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
// 推送的數(shù)據(jù),包含uid字段,表示是給這個uid推送
$data = array('uid'=>'uid1', 'percent'=>'88%');
// 發(fā)送數(shù)據(jù),注意5678端口是Text協(xié)議的端口,Text協(xié)議需要在數(shù)據(jù)末尾加上換行符
fwrite($client, json_encode($data)."\n");
// 讀取推送結果
echo fread($client, 8192);

這里的uid不一定是用戶的id,也可以理解為任務id即 taskid

記得開放1234 5678 兩個端口的防火墻。如果是云服務器,還要開放這兩個端口的安全組。

以上代碼親測可以直接使用

  • 人世幾回傷往事 2019-11-14

    @1 群主經(jīng)測試您給的后端代碼前端js,workerman推送代碼只對一個頁面有效,并不是對所有打開的頁面有效,我打算對所有頁面有效,我該怎么做呢?或者我如何設置成可以向所有打開頁面的uid推送。希望群主給點思路呀。

  • walkor 2019-11-14

    所有頁面uid傳同一個

  • 人世幾回傷往事 2019-11-14

    @1 群主push.php里面有broadcast方法向所有頁面推送,但是我前端js中怎樣把所有頁面uid傳同一個呢?如果所有頁面uid傳同一個的話那后端php代碼是不是不用向push.php發(fā)送指定的uid了呢?

  • 人世幾回傷往事 2019-11-14

    @1 群主我補充一下我的應用場景呀 我是在不同瀏覽器,或者不同的電腦下相同或不同的瀏覽器打開同一個頁面(網(wǎng)址一樣)讓他們都能推送,我已經(jīng)設置了定時刷新。我希望每個用戶打開這個界面都能定時看到推送。

  • 陸路 2019-12-15

    @2932:我也遇到同樣的問題,您怎么解決的?如果大家看到,麻煩也幫忙解答一下,著急,在線等

  • 凌笑然 2020-03-04

    @6607:Linux不能用應該是防火墻沒設置這個端口導致的,在防火墻加這條規(guī)則,然后重啟防火墻就可以了:-A INPUT -p tcp -m tcp --dport 1234 -j ACCEPT,我剛好遇到這個問題,這樣解決的

walkor 打賞

哈啰 !push.php line 4: $worker->count = 1;為什么只能設置一個進程啊

假如:
客戶端1連接進程A
客戶端2連接進程B

客戶端2無法直接通過進程B給客戶端1發(fā)送數(shù)據(jù),因為客戶端1屬于進程A不屬于進程B,B進程控制不到客戶端1(要想兩個進程之間通訊需要一些進程間通訊手段,可以使用http://doc3.workerman.net/component/channel.html)。
所以所有客戶端都只能連接同一個進程才能直接互相通訊,為了避免客戶端連到不同進程,count設置為1。

  • jackie 2019-01-24

    channel文檔中說在php-fpm無法使用,那么php-fpm下的多進程如何實現(xiàn)呢?

ivan

寫得太好了!

  • 我很恨你 2016-06-06

    問一下前段js和后端推送消息的代碼寫在哪里呢

  • ivan 2016-06-07

    @1080::前端js是用來連ws的,在你需要接收數(shù)據(jù)的地方寫上,后端推送的可以用老大的代碼用php寫 也可以隨便找tcp客戶端來實現(xiàn)。這兩個可以是獨立的跟workerman本身關系不大

workercat

我想問,workman 怎么與 PHP 腳本進行數(shù)據(jù)傳輸呢?

  • 暫無評論
walkor 打賞

@workercat 新問題請新建帖子。把問題描述清楚,不要問“一句話”問題,尤其不要問“XXXX怎么做“這種,這種太籠統(tǒng),沒法回。不同場景有不同的做法。

  • 暫無評論
workercat

執(zhí)行后端推送代碼時,出現(xiàn) unable to connect, connect refused. 請問這是什么原因造成的尼?我已經(jīng)更換了多個端口進行測試,依然是同樣的提示。還有什么測試方法和手段來找出原因嘛?

后端推送消息的代碼
// 建立socket連接到內(nèi)部推送端口
$client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT);
// 推送的數(shù)據(jù),包含uid字段,表示是給這個uid推送
$data = array('uid'=>'uid1', 'percent'=>'88%');
// 發(fā)送數(shù)據(jù),注意5678端口是Text協(xié)議的端口,Text協(xié)議需要在數(shù)據(jù)末尾加上換行符
fwrite($client, json_encode($data)."\n");
// 讀取推送結果
echo fread($client, 8192);

  • 暫無評論
workercat

workerman 代碼是完全與上面的一致。

  • 暫無評論
walkor 打賞

發(fā)生這個問題原因有
1.服務端沒啟動
2.端口錯誤
3.客戶端IP錯了
4.防火墻擋住了

  • 暫無評論
workercat

首先,我先建一個 ump worker , 再在 work 進程啟動后建立一個內(nèi)部通訊端口。然后,我再寫 php socket 腳本來反問內(nèi)部通訊端口,提示 connect refused。防火墻是否阻擋,端口是否被占用,服務是否開啟,客戶端鏈接的 ip 都這幾個問題都確認沒有問題。

結果,卻是一直提示 connection refused.

use Workerman\Worker;
    include './Workerman/Autoloader.php';

    $worker = new Worker("udp://192.168.50.190:8800");
    //var_dump($worker);
    $worker->count = 1;

    $worker->onWorkerStart = function ($worker)
    {
        // 用于 Laravel 與 Workerman 的內(nèi)部通訊
        $inner_text_worker = new Worker ("text://192.168.50.190:5678");

        // 接收到 Laravel 請求信息,就向設備發(fā)起 UDP 請求
        $inner_text_worker->onMessage = function ($connection, $arr_data)
        {

            $connection->send('success udp');
        };
    };

    //  接收 UDP 請求,如:心跳
    $worker->onMessage  = function ($connection, $data) 
    {
        echo $data . "<br/>";
        $client_ip = $connection->getRemoteIp();
        $client_port = $connection->getRemotePort();
        $connection->send(strrev($data));
    };

}}

// 開啟內(nèi)部通訊端口打印輸出的對象:object(Workerman\Worker)#6 (24) {
  =>
  int(0)
  =>
  string(4) "none"
  =>
  int(1)
  =>
  string(0) ""
  =>
  string(0) ""
  =>
  bool(true)
  =>
  bool(false)
  =>
  NULL
  =>
  NULL
  =>
  object(Closure)#7 (1) {
    =>
    _RECURSION_
  }
  =>
  NULL
  =>
  NULL
  =>
  NULL
  =>
  NULL
  =>
  NULL
  =>
  NULL
  =>
  string(3) "tcp"
  =>
  array(0) {
  }
  =>
  string(0) ""
  =>
  string(37) "/Library/WebServer/Documents/camerawk"
  =>
  NULL
  =>
  string(26) "text://192.168.50.190:5678"
  =>
  resource(17) of type (stream-context)
  =>
  string(32) "000000000f4c6bca0000000043696ce7"
}

// php socket 腳本對內(nèi)部端口通訊發(fā)起請求,報錯:stream_socket_client(): unable to connect to tcp://192.168.50.190:5678 (Connection refused)
  • 暫無評論
walkor 打賞

少了一句$inner_text_worker->listen();
歸根到底還是對應的端口服務沒啟動。

workercat

問題:如果我 new 的 worker 是監(jiān)聽是的 http 通訊 8080端口,當有接收到信息時,那么 workerman 的onMessage 方法執(zhí)行 $connection->send("message") 。

我的疑問時 $connection->send("message") 發(fā)送的信息,會以什么端口,從服務器發(fā)出去呢?

$worker->onMessage = function($connection, $data) use ($worker)
{
$connection->send("返回信息");
};

  • 暫無評論
walkor 打賞

@workercat 新問題開新的帖子吧。

  • 暫無評論
夏蟲

上面的沒看得太明白,push.php是運行在workman里面的 后端推送消息代碼是運行在web后臺的對嗎,通過后端推送消息代碼調(diào)用push.php.是這個思路嗎

  • 暫無評論
walkor 打賞

@夏蟲 對

  • 暫無評論
夏蟲

要實現(xiàn)我這種模式 問號部分該用什么方法實現(xiàn)呢

  • jackie 2019-01-24

    請問下你的問題解決了嗎?

  • adminppper 2019-12-31

    @5344:這個我很會玩,多進程服務器,你可以加我570600495

  • lloyou00 2020-03-04

    // 建立socket連接到內(nèi)部推送端口
    $client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
    // 推送的數(shù)據(jù),包含uid字段,表示是給這個uid推送
    $data = array('uid'=>'uid1', 'percent'=>'88%');
    // 發(fā)送數(shù)據(jù),注意5678端口是Text協(xié)議的端口,Text協(xié)議需要在數(shù)據(jù)末尾加上換行符
    fwrite($client, json_encode($data)."\n");
    // 讀取推送結果
    echo fread($client, 8192);

    這里不是寫得很清楚嘛?

    workerman 的文檔里面也有
    http://doc3.workerman.net/315240

    推薦使用 GatewayWorker 的方式

    本質(zhì)就是進程間通訊而已

小V

$inner_text_worker = new Worker('Text://0.0.0.0:5678');
第一次運行沒有問題,但第二次運行

fwrite($client, json_encode($data)."\n");
這里會報錯,換一個端口運行,又可以了,這是為什么呢?

  • walkor 2016-11-03

    把STREAM_CLIENT_PERSISTENT選項去掉就好了

  • walkor 2016-11-03

    改成 $client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);

  • 小V 2016-11-04

    可以了,點個贊

httpp886
use Yii;
use yii\console\Controller;
use \Workerman\Worker;
require_once 'vendor/autoload.php';

class WorkerController extends Controller {
    public function actionPush(){
        // 初始化一個worker容器,監(jiān)聽1234端口
        require_once dirname(Yii::$app->basePath).'/vendor/workerman/workerman/Autoloader.php';
        $worker = new Worker('websocket://127.0.0.1:1234');

        // 這里進程數(shù)必須設置為1
        $worker->count = 1;
        // worker進程啟動后建立一個內(nèi)部通訊端口
        $worker->onWorkerStart = function($worker)
        {
            // 開啟一個內(nèi)部端口,方便內(nèi)部系統(tǒng)推送數(shù)據(jù),Text協(xié)議格式 文本+換行符
            $inner_text_worker = new Worker('http://127.0.0.1:5678');
            $inner_text_worker->onMessage = function($connection, $buffer)
            {
                global $worker;
                // $data數(shù)組格式,里面有uid,表示向那個uid的頁面推送數(shù)據(jù)
                $data = json_decode($buffer, true);
                $uid = $data;
                // 通過workerman,向uid的頁面推送數(shù)據(jù)
                $ret = $this->sendMessageByUid($uid, $buffer);
                // 返回推送結果
                $connection->send($ret ? 'ok' : 'fail');
            };
            $inner_text_worker->listen();
        };
        // 新增加一個屬性,用來保存uid到connection的映射
        $worker->uidConnections = array();
        // 當有客戶端發(fā)來消息時執(zhí)行的回調(diào)函數(shù)
        $worker->onMessage = function($connection, $data)use($worker)
        {
            // 判斷當前客戶端是否已經(jīng)驗證,既是否設置了uid
            if(!isset($connection->uid))
            {
                // 沒驗證的話把第一個包當做uid(這里為了方便演示,沒做真正的驗證)
                $connection->uid = $data;
                /* 保存uid到connection的映射,這樣可以方便的通過uid查找connection,
                 * 實現(xiàn)針對特定uid推送數(shù)據(jù)
                 */
                $worker->uidConnections = $connection;
                return;
            }
        };

        // 當有客戶端連接斷開時
        $worker->onClose = function($connection)use($worker)
        {
            global $worker;
            if(isset($connection->uid))
            {
                // 連接斷開時刪除映射
                unset($worker->uidConnections);
            }
        };
        // 運行所有的worker(其實當前只定義了一個)
        Worker::runAll();
    }

    // 向所有驗證的用戶推送數(shù)據(jù)
    function broadcast($message)
    {
        global $worker;
        foreach($worker->uidConnections as $connection)
        {
            $connection->send($message);
        }
    }

    // 針對uid推送數(shù)據(jù)
    function sendMessageByUid($uid, $message)
    {
        global $worker;
        if(isset($worker->uidConnections))
        {
            $connection = $worker->uidConnections;
            $connection->send($message);
            return true;
        }
        return false;
    }

}

stream_socket_client(): unable to connect to tcp://127.0.0.1:5678 (???????????????????????

  • httpp886 2017-03-14

    老是返回上邊的錯誤,服務器端也運行成功(Press Ctrl-C to quit. Start success.)

  • httpp886 2017-03-14
    public function pushma($msg){
        header("Content-Type: text/html; charset=UTF-8");
        // 建立socket連接到內(nèi)部推送端口
        $client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
        // 推送的數(shù)據(jù),包含uid字段,表示是給這個uid推送
        $data = array('uid'=>'uid1', 'percent'=>$msg);
        // 發(fā)送數(shù)據(jù),注意5678端口是Text協(xié)議的端口,Text協(xié)議需要在數(shù)據(jù)末尾加上換行符
        fwrite($client, json_encode($data)."\n");
        // 讀取推送結果
        echo fread($client, 8192);
    }

    這是調(diào)用代碼

  • walkor 2017-03-14

    服務沒啟動成功導致的

  • Victoryship 2017-03-20

    @1:大佬問下,為什么我用例子發(fā)到客戶端瀏覽器上。消息顯示一下就馬上消失了?

  • walkor 2017-03-20

    估計你哪里沒弄好,要自己定位下

Victoryship

大佬問下,為什么我用例子發(fā)到客戶端瀏覽器上。消息顯示一下就馬上消失了?

  • 暫無評論
joy

一天中,經(jīng)常隔一兩小時,sendMessageByUid發(fā)送的結果是false,過一會兒又自己好了
查看狀態(tài)沒有false
這種情況,需要不需要心跳,本身已是長連接

  • joy 2017-04-01

    幾小時后,是連上了,可能是之前一直沒連上,回頭做個測試

walkor 打賞

如果需要鏈接長時間維持(大于1分鐘)必須加心跳??蛻舳硕〞r向服務端發(fā)送點心跳數(shù)據(jù)(數(shù)據(jù)任意,服務端能識別就行),服務端onMessage里判斷是心跳忽略即可。

樓主的需求是瀏覽器里展示進度,預期這個進度會在1分鐘內(nèi)完成,則不用加心跳。

  • 暫無評論
joy

加了心跳,但是
用的是winform接收的,打著斷點
第一次有,第二次執(zhí)行結果打印出來也是成功,win端但沒接收到任何消息

  • walkor 2017-03-31

    你可以抓包看鏈接建立了沒,數(shù)據(jù)推送過來沒。可能你的winform寫的有問題。
    你可以用上面demo寫的js在瀏覽器里試下。

joy

包括心跳回來的消息也一樣
長連接建立后,給子線程A發(fā),第一次正常接收,第二次接收到任務消息了

  • walkor 2017-03-31

    什么子線程?這個demo服務端是單進程單線程的,沒有子線程一說。

joy

[attach]574[/attach]
這個斷開,是否還要用心跳來判斷,還是內(nèi)部自動會判斷
如果沒發(fā)消息過來了,會不會就自己會斷開

  • walkor 2017-03-31

    這個demo心跳作用是用來防止鏈接由于長時間不活躍被路由節(jié)點防火墻關閉。如果你預計這個鏈接要維持很長時間(超過一分鐘),需要客戶端定時發(fā)一點數(shù)據(jù)給服務端,用來保持鏈接活躍。服務端onMessage里判斷下如果是心跳消息忽略即可。
    如果鏈接預計低于一分鐘,可以不用發(fā)心跳。

  • 寓言 2018-11-20

    @1:walkor大神,正如我昨天提的那個問題,如果后端消息不停推送,在onMessage里面是沒法收到消息的,只能等后端消息推送完畢后,才能接受到,可能這時候已經(jīng)超過了后端設置的心跳時間(比如1分鐘),就會在onclose主動關閉客戶端連接,然后客戶端重新連接,這中間的數(shù)據(jù)就會丟失,這種情況怎么解決呢?

joy

需要在子線程上加
[attach]575[/attach]
來監(jiān)測關閉嗎?
如何加?

  • walkor 2017-03-31

    這個demo不用加這個邏輯

joy

感覺很不穩(wěn)定,不知應該怎么來調(diào)試
客戶端寫了心跳,比之前的沒心跳的,連接情況更差
消息返回成功的很少,而且即使返回成功,但客戶端,還是沒有接收到數(shù)據(jù)

以前一兩小時,發(fā)生三四次失敗,現(xiàn)在是經(jīng)常失敗

  • 暫無評論
walkor 打賞

可能你的客戶端還沒連上,你就開始從后端push消息了,這個demo里沒做消息緩存,如果客戶端不存在就直接把消息丟棄了。
自己多打打日志服務端抓抓包定位下吧,從你的描述中無法幫到你。
這個demo是沒問題的,很多人在用了。

  • 暫無評論
joy

心跳處理這樣可以吧?不需要到5678端口上吧

[attach]576[/attach]

  • joy 2017-04-01

    運行幾小時后,好像又連上了,那心跳是不是可以這樣處理,不需要轉到mridConnections子連接里去

  • joy 2017-04-01

    因為是異步消息處理,所以還是要用這個長鏈接,用戶手機上傳東西,就自動發(fā)個消息給我這邊的客戶端,通知一下,有沒有其他更好的處理方式

  • walkor 2017-04-01

    可以這樣處理。5678端口是短鏈接,不用設置心跳

php_zdg

按照demo代碼來,php運行一直返回fail,是那個映射問題嗎?好像不能找到制定客戶端啊

mir_gong

按照demo代碼來,php運行一直返回fail.怎么解決~

walkor 打賞

返回fail很明顯對應uid沒在線

  • 吃嘛嘛香 2018-12-12

    大佬 一直返回fail,這個問題怎么解決呀

xiaoxiaolu

寫的比較好,測試沒問題,很好解決了PHP客戶端與web socket端之間的數(shù)據(jù)監(jiān)聽通訊

  • xiaoxiaolu 2018-05-10

    php客戶端推送數(shù)據(jù)給web端容易產(chǎn)生數(shù)據(jù)丟失

  • 18117303062 2018-07-28

    我測試的時候也發(fā)現(xiàn)這個情況,但原因是因為時間長了和服務器斷開連接了,這樣父進程weibsocket里原來的uid1已經(jīng)刪除了,這個時候php客戶端發(fā)送數(shù)據(jù),數(shù)據(jù)其實服務端的子進程接收到了,但由于沒有找到uid,所以php客戶端沒有收到回復。加上心跳,代碼邏輯上再優(yōu)化些應該可以解決。

dxyzz

大佬們,
能不能問一下你這個問題的第三部分:后端推送消息的代碼

這一部分代碼是應該寫在哪里哦?跟后端代碼寫一個類里面么?新手求指點。。。

  • 暫無評論
hehe

看看這個workerman實戰(zhàn)視頻,保準都會了

http://study.163.com/course/introduction/1005015012.htm?share=2&shareId=400000000388007

  • 暫無評論
18117303062

寫得很好,學習了。我是新手,能發(fā)表下學習體會嗎?

  • 暫無評論
18117303062

總體上該方案非常優(yōu)秀,框架大概二個部分,第一個是websocket作為服務端接收和發(fā)送消息的父進程,不妨稱之為fatherWorker,比較巧妙的是在該對象里嵌套了一個TEXT協(xié)議的worker,不妨叫他childWorker,這個功能用一個PHP頁面就能解決。第二個是客戶端,該客戶端可以用本地建立一個簡單網(wǎng)站實現(xiàn),用來登錄界面操作,里面兩個頁面,第一個頁面是用來和服務端的父進程websocket建立連接,并發(fā)送UID的,這個頁面可以是普通的html頁面。第二個頁面是用來和服務端的子進程TEXT協(xié)議建立連接的,其作用是發(fā)送UID編號和數(shù)據(jù),這里要注意的是兩個頁面的UID號必須一致,否則發(fā)送失敗。
這樣,三個頁面,實現(xiàn)了WEB服務、SOCKET服務和TEXT協(xié)議服務三者聯(lián)動的效果,構思巧妙,非常優(yōu)秀!

  • 暫無評論
18117303062

代碼我依樣畫葫蘆測試過了,沒有問題,感謝分享,我剛學習workerman,說些自己的理解,不當之處大家指正。

  • 暫無評論
wegl

workerman新手,根據(jù)自己入門經(jīng)歷的疑惑,講一下表面的小白使用問題,也是新手小白容易產(chǎn)生的疑惑:
可以確定,下載workerman最新版,不修改示例代碼,示例代碼是百分百可以在linux和windows都可以正常運行的。
windows中出現(xiàn)的問題:
(1)、執(zhí)行順序!一定不能錯:第一步,php push.php,第二步,瀏覽器的頁面上運行執(zhí)行js ,第三步,執(zhí)行stream_socket_client的5678端口的那段代碼

(2)、windows本機測試中,第二步的js,可以在任何一個瀏覽器的console中執(zhí)行,但是要注意,如果是打算把js放進自己寫的html頁面,是無法用本地windows的apache服務訪問頁面的,原因應該就是windows下php只能用一個進程,而php進程已經(jīng)被第一步占用。同樣,第三步,也不能用windows本機的apache請求頁面或者php命令行執(zhí)行php,可以通過telnet 127.0.0.1:5678的方式,輸入:{"uid":"uid1","percent":"2%"},瀏覽器js就可以收到了

(3)、這個代碼是可以調(diào)試的(好像是廢話)。可能對于小白而言,因為對workerman陌生一時忘記了怎么調(diào)試。其實和普通的php開發(fā)一樣,可以直接echo/var_dump打印輸出,也可以記錄到文件里。
telnet 127.0.0.1 5678 的命令下,也可以調(diào)試5678接收第三步消息的信息:push.php代碼里,在$connection->send($ret ? 'ok' : 'fail');前,加上自己要調(diào)試的內(nèi)容send即可,如:$connection->send($buffer);
? ?!! push.php調(diào)試代碼修改后,一定要重新啟動第一步(linux下restart/reload;windows下退出進程,重新執(zhí)行),才能生效
? ? linux下執(zhí)行php push.php start 后面不加-d,不讓后臺運行,可以查看打印出的調(diào)試輸出

(4)、一旦出現(xiàn)問題,檢查步驟:
? ? ? 1、telnet 127.0.0.1 1234
? ? ? ? ? ?telnet 127.0.0.1 5678
? ? ? ? ?如果不通,端口是否開啟,linux下檢查iptables
? ? ? 2、如果是第三步返回fail,一般是uid用戶連接斷開了,只需要瀏覽器重新執(zhí)行一下第二步js,在重新執(zhí)行第三步

  • 暫無評論
json_decode

向端口推送數(shù)據(jù)的時候,返回的一致是false;

$client = stream_socket_client('tcp://127.0.0.1:2345',$error,$errmsg,1);
var_dump($client);
//推送的數(shù)據(jù),包含的uid字段,表示給這個用戶uid推送
$data = array('uid'=>'uid1', 'percent'=>'88%');
fwrite($client, json_encode($data)."\n");
echo fread($client, 8192);

  • xiuwang 2020-06-17

    這是返回fail,不是false。返回fail應該是對應的uid沒在線,沒有對應的websocket連接

yangyu

大佬呀,為啥向端口推送數(shù)據(jù)的時候,返回的一致是false呀
$client = stream_socket_client('tcp://127.0.0.1:2345',$error,$errmsg,1);
var_dump($client);

  • 暫無評論
hfxlyf

大家看看我寫的對著沒 通過http給客戶端推送tcp消息
https://github.com/phpyii/workerman-test/tree/master/test/tcp

  • 暫無評論
workenman

收藏

  • 暫無評論
年代過于久遠,無法發(fā)表回答
??