十七、Swoole 基础学习笔记 - Swoole 初始并体验 WebSocket

作者: 温新

分类: 【Swoole 系列】

阅读: 1474

时间: 2023-03-13 11:27:08

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 中,onOpenonMessage 属于 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 WebSocketOPCode 类型,可以参考 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。

请登录后再评论