WebSocket 异步风格服务器

WebSocket\Server 继承自 Http\Server,所以 Http\Server 提供的所有 API 和配置项都可以使用。

# ws_server.php

class WebSocket
{
public $server; public function __construct()
{
// 创建websocket服务器对象,监听0.0.0.0:9502端口
$this->server = new Swoole\WebSocket\Server("0.0.0.0", 9502); // 设置服务器运行参数
$this->server->set(array(
'daemonize' => 1, // 作为守护进程运行,需同时设置log_file
'log_file' => '/www/logs/swoole.log', // 指定标准输出和错误日志文件
)); // 监听WebSocket连接打开事件
$this->server->on('open', function ($ws, $request) {
var_dump($request->fd, $request->get, $request->server);
$ws->push($request->fd, "hello, welcome\n");
}); // 监听WebSocket消息事件
$this->server->on('message', function ($ws, $frame) {
echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
$ws->push($frame->fd, "server: {$frame->data}");
}); // 监听WebSocket连接关闭事件
$this->server->on('close', function ($ws, $fd) {
echo "client {$fd} is closed\n";
}); // 通过 HTTP 请求向所有用户推送消息
$this->server->on('request', function ($request, $response) {
foreach ($this->server->connections as $fd) {
// 检查连接是否为有效的 WebSocket 客户端连接,避免push失败
if ($this->server->isEstablished($fd)) {
$this->server->push($fd, $request->get['message']);
}
}
}); $this->server->start();
}
} // 启动 WebSocket 服务器
new WebSocket();

运行并测试 WebSocket 异步风格服务器

# 如果程序已经运行,先结束进程
kill -9 11591 # 在 cli 命令行环境运行服务端
php ws_server.php # 查看服务器监听的端口
netstat -an | grep 9502

WebSocket JS客户端

# index.js

var wsServer = 'ws://127.0.0.1:9502';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("Connected to WebSocket server.");
websocket.send('hello ws!');
}; websocket.onclose = function (evt) {
console.log("Disconnected");
}; websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
}; websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};

客户端

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

WebSocket 协程风格服务器

Co\run(function () {
$server = new Co\Http\Server("127.0.0.1", 9502, false); // 设置服务器运行参数
$server->set(array(
'daemonize' => 1, // 作为守护进程运行,需同时设置log_file
'log_file' => '/www/logs/swoole.log', // 指定标准输出和错误日志文件
)); $server->handle('/websocket', function ($request, $ws) {
// 向客户端发送 WebSocket 握手消息
$ws->upgrade(); // 循环处理消息的接收和发送
while (true) {
// 接收 WebSocket 消息帧,会挂起当前协程,等待数据到来时再恢复协程的执行
$frame = $ws->recv();
if ($frame === false) {
echo "error : " . swoole_last_error() . "\n";
break;
} else if ($frame == '') {
break;
} else {
if ($frame->data == "close") {
$ws->close();
return;
} // 向对端发送数据帧
$ws->push("Hello {$frame->data}!");
$ws->push("How are you, {$frame->data}?");
}
}
}); $server->handle('/', function ($request, $response) {
$response->end(<<<HTML
<h1>Swoole WebSocket Server</h1>
<script>
var wsServer = 'ws://127.0.0.1:9502/websocket';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("Connected to WebSocket server.");
websocket.send('hello');
}; websocket.onclose = function (evt) {
console.log("Disconnected");
}; websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
}; websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
</script>
HTML
);
}); $server->start();
});

WebSocket 协程客户端

官方建议使用 Saber

Swoole 中使用 WebSocket 异步服务器、WebSocket 协程服务器的更多相关文章

  1. day37 异步回调和协程

    异步回调 """ 异步任务使用场景 爬虫 1.从目标站点下载网页数据 本质就是HTML格式字符串 2.用re从字符串中提取出你需要的数据 ""&quo ...

  2. Python的异步编程[0] -> 协程[1] -> 使用协程建立自己的异步非阻塞模型

    使用协程建立自己的异步非阻塞模型 接下来例子中,将使用纯粹的Python编码搭建一个异步模型,相当于自己构建的一个asyncio模块,这也许能对asyncio模块底层实现的理解有更大的帮助.主要参考为 ...

  3. Python异步IO之协程(一):从yield from到async的使用

    引言:协程(coroutine)是Python中一直较为难理解的知识,但其在多任务协作中体现的效率又极为的突出.众所周知,Python中执行多任务还可以通过多进程或一个进程中的多线程来执行,但两者之中 ...

  4. 深入浅析python中的多进程、多线程、协程

    深入浅析python中的多进程.多线程.协程 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源 ...

  5. 进程&线程(三):外部子进程subprocess、异步IO、协程、分布式进程

    1.外部子进程subprocess python之subprocess模块详解--小白博客 - 夜风2019 - 博客园 python subprocess模块 - lincappu - 博客园 之前 ...

  6. Swoole 中使用 TCP 异步服务器、TCP 协程服务器、TCP 同步客户端、TCP 协程客户端

    TCP 异步风格服务器 异步风格服务器通过监听事件的方式来编写程序.当对应的事件发生时底层会主动回调指定的函数. 由于默认开启协程化,在回调函数内部会自动创建协程,遇到 IO 会产生协程调度,异步风格 ...

  7. Swoole 中使用 HTTP 异步服务器、HTTP 协程服务器

    HTTP 异步风格服务器 # http_server.php $http = new Swoole\Http\Server("0.0.0.0", 9501); // 设置服务器运行 ...

  8. Swoole 中使用 UDP 异步服务器、UDP 同步客户端、UDP 协程客户端

    UDP 异步风格服务器 # udp_server.php // 创建 UDP 服务器对象,监听0.0.0.0:9502端口,类型为SWOOLE_SOCK_UDP $serv = new Swoole\ ...

  9. Python 中的进程、线程、协程、同步、异步、回调

    进程和线程究竟是什么东西?传统网络服务模型是如何工作的?协程和线程的关系和区别有哪些?IO过程在什么时间发生? 一.上下文切换技术 简述 在进一步之前,让我们先回顾一下各种上下文切换技术. 不过首先说 ...

随机推荐

  1. spring注解-bean生命周期

    https://www.jianshu.com/p/70b935f2b3fe bean的生命周期 bean创建---初始化----销毁的过程 容器管理bean的生命周期 对象创建:容器启动后调用bea ...

  2. MyBatis(3):优化MyBatis配置文件

    一.连接数据库的配置单独放在一个properties文件中 1,创建一个database.properties driver=com.mysql.jdbc.Driver url=jdbc:mysql: ...

  3. MyBatis(1):实现MyBatis程序

    一,MyBatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...

  4. vueAPI (data,props,methods,watch,computed,template,render)

    data Vue 实例的数据对象.Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化.实例创建之后,可以通过vm.$data来访问原始数据 ...

  5. 多媒体音视频处理及FFmpeg使用技巧总结

    截图 ffmpeg -ss 00:02:06 -i input.mp4 -f image2 -y poster.jpg 连续截图 ffmpeg -y -i input.mp4 -vf "fp ...

  6. 【JS】原生实现拖拽

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  7. 关于tensorflow无法使用gpu

    python3.6 无法使用tensorflow gpu 环境名称 test1 在控制台里进入环境 conda activate test1 使用python python 查看gpu能否使用 pri ...

  8. Table.Distinct取唯/众数….Distinct/Mode/判断…IsDistinct(Power Query 之 M 语言)

    数据源: "姓名""基数""个人比例""个人缴纳""公司比例""公司缴纳"&qu ...

  9. CF1080B Margarite and the best present 题解

    Content 有 \(t\) 次询问,每次询问给定两个整数 \(l,r\),求 \(\sum\limits_{i=l}^r (-1)^i\times i\). 数据范围:\(1\leqslant t ...

  10. 在执行java代码时,设置了断点,然后莫名的没执行完方法内的代码就结束了,此刻一般在出错处代码用try,catch包括起来

    在执行java代码时,设置了断点,然后莫名的没执行完方法内的代码就结束了,此刻一般在出错处代码用try,catch包括起来就能看到是什么异常了,记住try,catch语句的作用