十七、Swoole 基础学习笔记 - Swoole 初始并体验 WebSocket
hi,我是温新,一名PHPer
文章基于 Swoole 5.0.1 版本编写。
学习目标:掌握 websocket 的使用
说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!
什么是 WebSocket
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信,即允许服务器主动发送信息给客户端。因此,在WebSocket中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输,客户端和服务器之间的数据交换变得更加简单。
WebSocket 的特点
- 1、建立在 TCP 协议之上,服务器端的实现比较容易;
- 2、数据格式比较轻量,性能开销小,通信高效;
- 3、没有同源限制,客户端可以与任意服务器通信;
- 4、协议标识符是
ws
(如果加密,则为wss
),服务器网址就是 URL; - 5、持久化网络通信协议(长连接)。
使用场景
业务场景 | 场景概述 |
---|---|
弹幕 | 终端用户A 要在自己的手机端发送了一条弹幕信息,但是您也需要在客户A的手机端上将其他N个客户端发送的弹幕信息一并展示。需要通过 WebSocket 协议将其他客户端发送的弹幕信息从服务端全部推送至客户A的手机端,从而使客户A可以同时看到自己发送的弹幕和其他用户发送的弹幕。 |
在线教育 | 老师进行一对多的在线授课,在客户端内编写的笔记、大纲等信息,需要实时推送至多个学生的客户端,需要通过 WebSocket 协议来完成。 |
股票等金融产品实时报价股 | 股票黄金等价格变化迅速,变化后,可以通过 WebSocket 协议将变化后的价格实时推送至世界各地的客户端,方便交易员迅速做出交易判断。 |
体育实况更新 | 由于全世界体育爱好者数量众多,因此比赛实况成为其最为关心的热点。这类新闻中最好的体验就是利用 WebSocket 达到实时的更新。 |
视频会议和聊天 | 尽管视频会议并不能代替和真人相见,但是应用场景众多。WebSocket 可以帮助两端或多端接入会议的用户实时传递信息。 |
基于位置的应用 | 越来越多的开发者借用移动设备的 GPS 功能来实现基于位置的网络应用。如果您一直记录终端用户的位置(例如:您的 App 记录用户的运动轨迹),就可以收集到更加细致化的数据。 |
Swoole WebSocket 相关回调函数
在 Swoole 中,onOpen
、onMessage
属于 websocket 服务。
onOpen
含义:当 WebSocket
客户端与服务器建立连接并完成握手后会回调此函数。
onOpen(Swoole\WebSocket\Server $server, Swoole\Http\Request $request);
- $reqeust,是一个 Http 请求对象,包含了客户端发送来的握手请求信息;
-
onOpen
事件函数中可以调用 push 向客户端发送数据或调用 close 关闭连接; -
onOpen
事件回调是可选的。
onMessage
含义:当服务器收到来自客户端的数据帧时会回调此函数。
onMessage(Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame)
- $frame,包含了客户端发来的数据帧信息;
-
onMessage
回调必须被设置,未设置服务器将无法启动; - 客户端发送的
ping
帧不会触发onMessage
,底层会自动回复pong
包。
$frame
共有 4 个属性:
-
Swoole\WebSocket\Frame $frame
属性 | 说明 |
---|---|
$frame->fd | 客户端的 socket id ,使用 $server->push 推送数据时需要用到 |
$frame->data | 数据内容,可以是文本内容也可以是二进制数据,可以通过 opcode 的值来判断 |
$frame->opcode | WebSocket 的 OPCode 类型,可以参考 WebSocket 协议标准文档 |
$frame->finish | 表示数据帧是否完整,一个 WebSocket 请求可能会分成多个数据帧进行发送(底层已经实现了自动合并数据帧,现在不用担心接收到的数据帧不完整) |
Swoole WebSocket 体验
服务端代码
<?php
// 16-swoole-websocket-1.php
$server = new Swoole\WebSocket\Server('0.0.0.0', 9501);
// 监听客户端连接
$server->on('Open', function ($server, $request) {
print_r($request);
$server->push($request->fd, 'hello WebSocket');
});
// 监听客户端发送的数据
$server->on('Message', function ($server, $frame) {
echo $frame->data . PHP_EOL;
});
// 监听连接关闭
$server->on('Close', function ($server, $fd) {
echo '关闭客户端:' . $fd . PHP_EOL;
});
// 启动服务
$server->start();
客户端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 实例 websocket 对象
let ws = new WebSocket('ws://127.0.0.1:9501');
// 连接服务器
ws.onopen = function(event) {
ws.send('client info');
console.log(event.data)
}
// 接收服务端消息
ws.onmessage = function (event) {
// 接收服务端发送的数据
let data = event.data
console.log(event)
}
// 关闭连接
ws.onclose = function(event) {
console.log('关闭客户端链接');
}
</script>
</body>
</html>
本篇文章对 Swoole WebSocket 作了一个快速体验,下篇文章继续学习 WebSocket。
请登录后再评论