之前七七八八也发过一下相关文章,但是比较乱,所以从本章节开始,进行系统性整理输出一下。——开源技术小栈
什么是 WebSocket
WebSocket是一种通信协议,可在单个TCP连接上进行全双工通信。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以建立持久性的连接,并进行双向数据传输。
典型握手通信
客户端请求
GET /chat HTTP/1.1
Host: wss.tinywan.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
服务器响应
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
客户端的简单示例
var ws = new WebSocket("wss://echo.websocket.org");
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
ws.close();
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
实战
实战相关框架和插件组件统一使用超高性能可扩展PHP框架:webman 以及生态进行编写。
安装webman框架
如何安装使用请查阅文章 Webman:您的专属HTTP代理服务器,让网络浏览更加畅快!,这里不再详细阐述。
安装GatewayWorker插件
简介
GatewayWorker基于Workerman开发的一个项目框架,用于快速开发TCP长连接应用,例如app推送服务端、即时IM服务端、游戏服务端、物联网、智能家居等等
GatewayWorker使用经典的Gateway和Worker进程模型。Gateway进程负责维持客户端连接,并转发客户端的数据给BusinessWorker进程处理,BusinessWorker进程负责处理实际的业务逻辑(默认调用Events.php处理业务),并将结果推送给对应的客户端。Gateway服务和BusinessWorker服务可以分开部署在不同的服务器上,实现分布式集群。
GatewayWorker提供非常方便的API,可以全局广播数据、可以向某个群体广播数据、也可以向某个特定客户端推送数据。配合Workerman的定时器,也可以定时推送数据。
安装
D:dnmpwwwwebman-admin>composer require webman/gateway-worker
./composer.json has been updated
Running composer update webman/gateway-worker
Loading composer repositories with package information
Updating dependencies
Lock file operations: 2 installs, 0 updates, 0 removals
- Locking webman/gateway-worker (v1.0.8)
- Locking workerman/gateway-worker (v3.1.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 2 installs, 2 updates, 0 removals
- Downloading tinywan/jwt (v1.8.2)
- Downloading workerman/gateway-worker (v3.1.1)
- Downloading webman/gateway-worker (v1.0.8)
- Downloading workbunny/webman-nacos (1.1.7)
- Upgrading tinywan/jwt (v1.8.1 => v1.8.2): Extracting archive
- Installing workerman/gateway-worker (v3.1.1): Extracting archive
- Installing webman/gateway-worker (v1.0.8): Extracting archive
- Downgrading workbunny/webman-nacos (1.1.8 => 1.1.7): Extracting archive
> supportPlugin::install
> supportPlugin::install
Generating autoload files
29 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found
Using version ^1.0 for webman/gateway-worker
安装成功后配置文件目录路径
业务文件路径
跳转进程配置文件
use WebmanGatewayWorkerGateway;
use WebmanGatewayWorkerBusinessWorker;
use WebmanGatewayWorkerRegister;
return [
'gateway' => [
'handler' => Gateway::class,
'listen' => 'websocket://0.0.0.0:8783',
'count' => cpu_count(),
'reloadable' => false,
'constructor' => ['config' => [
'lanIp' => '127.0.0.1',
'startPort' => 2300,
'pingInterval' => 25,
'pingData' => '{"type":"ping"}',
'registerAddress' => '127.0.0.1:12306',
'onConnect' => function(){},
]]
],
'worker' => [
'handler' => BusinessWorker::class,
'count' => cpu_count()*2,
'constructor' => ['config' => [
'eventHandler' => pluginwebmangatewayEvents::class,
'name' => 'ChatBusinessWorker',
'registerAddress' => '127.0.0.1:12306',
]]
],
'register' => [
'handler' => Register::class,
'listen' => 'text://127.0.0.1:12306',
'count' => 1, // Must be 1
'constructor' => []
],
];
注意:
websocket
端口8783
。注册中心register
端口12306
启动服务
打开浏览器console
进行测试
var ws = new WebSocket("ws://127.0.0.1:8387");
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
ws.close();
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
进阶
编写业务配置
修改
pluginwebmangatewayEvents.php
业务处理事件onMessage()
方法
/**
* @desc onMessage
* @param string $clientId
* @param string $message
* @return false
* @author Tinywan(ShaoBo Wan)
*/
public static function onMessage(string $clientId, string $message): bool
{
$originMessage = json_decode($message, true);
if (json_last_error() != JSON_ERROR_NONE) {
Gateway::closeClient($clientId, json_encode([
'code' => 500,
'msg' => '无效的json数据'
], JSON_UNESCAPED_UNICODE));
return false;
}
return Gateway::sendToClient($clientId, json_encode([
'code' => 200,
'msg' => '请求发送成功',
'data' => $originMessage
], JSON_UNESCAPED_UNICODE));
}
无效数据
console 控制台
网络发送和接受情况
有效数据
var ws = new WebSocket("ws://127.0.0.1:8783");
ws.onopen = function(evt) {
console.log("Connection open ...");
let $_content = {
"mode": 1,
"from_username": "Tinywan",
"to_user_id": "10000",
"content": "Hi, 开源技术小栈",
};
ws.send(JSON.stringify($_content));
};
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
console 控制台
网络发送和接受情况
源码
文章相关源码地址:https://github.com/Tinywan/webman-admin
原文始发于微信公众号(开源技术小栈):「IM系列」WebSocket实践教程:基础入门实战
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/248007.html