WebSocket [编辑本页]

swoole-1.7.9 增加了内置的websocket服务器支持,通过几行PHP代码就可以写出一个异步非阻塞多进程的WebSocket服务器。

$server = new swoole_websocket_server("0.0.0.0", 9501);

$server->on('open', function (swoole_websocket_server $server, $request) {
    echo "server: handshake success with fd{$request->fd}\n";
});

$server->on('message', function (swoole_websocket_server $server, $frame) {
    echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
    $server->push($frame->fd, "this is server");
});

$server->on('close', function ($ser, $fd) {
    echo "client {$fd} closed\n";
});

$server->start();

onRequest回调

swoole_websocket_server 继承自 swoole_http_server

  • 设置了onRequest回调,websocket服务器也可以同时作为http服务器
  • 未设置onRequest回调,websocket服务器收到http请求后会返回http 400错误页面

客户端

  • Chrome/Firefox/高版本IE/Safari等浏览器内置了JS语言的WebSocket客户端
  • 微信小程序开发框架内置的WebSocket客户端
  • 异步的PHP程序中可以使用Swoole\Http\Client作为WebSocket客户端
  • apache/php-fpm或其他同步阻塞的PHP程序中可以使用swoole/framework提供的同步WebSocket客户端
  • 非WebSocket客户端不能与WebSocket服务器通信

  • 松松饭

    1.7.14版本下, on和message的参数都报错了,有新版的手册吗?

  • 松松饭

    看了下源码,1.7.14版 "on"的参数是 :function (swoole_websocket_server $server, swoole_http_request $req) "message"的参数是:function (swoole_websocket_server $server, swoole_websocket_frame $frame)

  • 张良晖

    message和close事件都是server上的?不应该是connection上的事件吗

  • nfer

    能否也对应的开发一个 swoole_websocket_client

  • 霸气千秋

    源码的 example/websocket 目录下有个 php 实现的 WebSocketClient

  • 刘朱石强

    websocket 下 $server->set(array('worker_num' => 1)); 不管用。

  • 刘朱石强

    搞错了,$server->set(array('worker_num' => 1)); 可以正常使用。

  • Just_Fee1ing

    PHP Fatal error: swoole_server::on(): Unknown event types[message] 就我一个人报这个error? swoole版本1.7.17

  • Just_Fee1ing

    饿。。知道咋回事了。。

  • guoerwei

    Argument 2 passed to {closure}() must be an instance of swoole_http_request, integer given on.('open')里面第二个参数传进来的是一个整数…

  • guoerwei

    同样on('message')的时候,$frame传进来也是一个整数int(1)…

  • guoerwei

    哦…之前是1.7.11,现在是1.7.17,正常了

  • 小马哥

    我怎么就 new swoole_server("127.0.0.1", 9501); 能连接上, new swoole_http_server("127.0.0.1", 9501); 和 new swoole_websocket_server("0.0.0.0", 9501); 都链接不上 ,版本 1.7.19

  • 爱好者

    有没有函数判断客户端还正在链接呢

  • 阿强

    今天试难成功,连上了,按照github上的例子连了一下,服务器端的信息: PHP Notice: Undefined property: swoole_http_request::$get in /var/www/html/ws.php on line 5 int(1) NULL array(9) { ["request_method"]=> string(3) "GET" ["request_uri"]=> string(1) "/" ["path_info"]=> string(1) "/" ["request_time"]=> int(1447532507) ["server_port"]=> int(9502) ["remote_port"]=> int(53188) ["remote_addr"]=> string(13) "192.168.1.102" ["server_protocol"]=> string(8) "HTTP/1.1" ["server_software"]=> string(18) "swoole-http-server" }

  • xcwenn@qq.com

    android 哪个websocket lib 合适?!

  • 他的流年

    您好,请问我如何在服务器主动关闭一个连接呢?

  • 他的流年

    不好意思,问题已解决。是我看得不够清楚,由继承关系直接调用close函数就可以关闭连接

  • seven

    我也想知道 怎么主动关闭一个连接 没看到你的什么意思 求大大给个代码案例看呢

  • 孙佳兵

    为什么我在客户端的js方法 socket.onopen能够相应,socket.opmessage响应不了?

  • jimmy

    swoole_websocket_server 的工作进程数怎么控制?

  • heice

    在吗?请问这个要怎么实现? 接收到redis的数据又把数据从websocket传出去 var app = require('http').createServer(handler); var io = require('socket.io')(app);

    var Redis = require('ioredis'); var redis = new Redis('6379','127.0.0.1');

    app.listen(6001, function() { console.log('Server is running!'); });

    function handler(req, res) { res.writeHead(200); res.end(''); }

    io.on('connection', function(socket) { // console.log('connected'); });

    redis.psubscribe('*', function(err, count) { // console.log('count'); });

    redis.on('pmessage', function(subscribed, channel, message) { console.log(subscribed); console.log(channel); console.log(message); message = JSON.parse(message); io.emit(channel + ':' + message.event, message.data); });

  • 骑驴泡美妞

    您好,可以问下是怎么解决的么?

  • 别怕

    页面直接写上这段js就行吗?为什么我在命令行运行之后 打开有这段js的页面什么也不显示?如果直接输入地址加上端口号的就出来一个websocket已经通电的话

  • 谭少民-倬余

    请问如何分房间?

  • 猫爸爸

    求助大大们,websocket 在IE11下上传超过50M的文件时提示,报文过长然后自动断开了,这是BUG还是我方式不对?chrome没有相关的问题,前端使用FileReader.readAsArrayBuffer()读取文件 WARNING swProtocol_recv_check_length: package is too big, remote_addr=192.168.5.1:52151, length=50772334. [/documents/bin/swoole-src-master/src/network/Port.c:340@swPort_onRead_check_length]Close Event.FD=32|From=0 client 1 quit

  • 谭少民-倬余

    请问单个服务端最大支持多少链接数?

  • 张三丰

    参照max_connection配置

  • 张三丰

    分房间应该是自己业务层去自己实现

  • d7788250

    Swoole\Http\Client作为WebSocket客户端有例程吗?

  • 快捷方式

    server: handshake success with fd1 receive from 1:hello yii,opcode:1,fin:1 client 1 closed [2017-04-20 15:14:42 #11571.2] WARNING swReactorThread_send: connection#18 is closed by client. server: handshake success with fd2 receive from 2:hello yii,opcode:1,fin:1 client 2 closed [2017-04-20 15:14:45 #11571.2] WARNING swReactorThread_send: connection#18 is closed by client. server: handshake success with fd3 receive from 3:hello yii,opcode:1,fin:1 client 3 closed [2017-04-20 15:14:48 #11571.2] WARNING swReactorThread_send: connection#18 is closed by client. server: handshake success with fd4 receive from 4:hello yii,opcode:1,fin:1 client 4 closed [2017-04-20 15:14:51 #11571.2] WARNING swReactorThread_send: connection#18 is closed by client. server: handshake success with fd5 receive from 5:hello yii,opcode:1,fin:1 client 5 closed [2017-04-20 15:14:53 #11571.2] WARNING swReactorThread_send: connection#18 is closed by client.

  • 快捷方式

    $webSocketClient = new \app\exts\WebSocketClient('121.11.71.33', 8988);

        $webSocketClient->connect();
    
        $webSocketClient->send('hello yii');
    
        $webSocketClient->close();
    

  • 快捷方式

    $server = new \swoole_websocket_server("121.11.71.33", 8988);

        $server->on('open', function (\swoole_websocket_server $server, $request) {
            echo "server: handshake success with fd{$request->fd}\n";
        });
    
        $server->on('message', function (\swoole_websocket_server $server, $frame) {
            echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
            $server->push($frame->fd, "this is server");
        });
    
        $server->on('close', function ($ser, $fd) {
            echo "client {$fd} closed\n";
        });
    
        $server->start();
    

  • 快捷方式

    为什么close之后还有warning,这是哪里给clien发送信息了吗

  • 王子

    请问如何使用websocket做分布式转发服务端?貌似swoole的websocket只有server,没有client