天天看点

Swoole基础——04 Websocket定义使用websocket完整实例完整实例(oop)

定义

Websocket是基于TCP的一种新的网络协议。

它实现了浏览器与服务器全双工通信——允许服务器主动发送信息给客户端。

为什么需要websocket?

1)HTTP的通信,只能由客户端发起;

2)websock有以下特点:

  • 建立在TCP协议上
  • 性能开销小,通信高效
  • 客户端可以与任意服务器通信
  • 协议标识符ws wss
  • 持久化网络通信协议(长链接)

使用websocket

WebSocket服务器是建立在Http服务器之上的长连接服务器,客户端首先会发送一个Http的请求与服务器进行握手。

握手成功后会触发onOpen事件,表示连接已就绪,onOpen函数中可以得到$request对象,包含了Http握手的相关信息,如GET参数、Cookie、Http头信息等。

(1) 创建websocket对象

(2)完成连接事件(可选)

当WebSocket客户端与服务器建立连接并完成握手后,会回调此函数。

$ws->on('open', function ($ws, $request) {
	...
});
           

(3)收到客户端数据事件(必选)

$ws->on('message', function ($ws, $frame) {
	...
});
           

$frame 是swoole_websocket_frame对象,包含了客户端发来的数据帧信息。

详情请看下图:

Swoole基础——04 Websocket定义使用websocket完整实例完整实例(oop)

(4)推送数据到客户端

// 第一种模式1.7.11+可用
$ws->push(int $fd, string $data, int $opcode = 1, bool $finish = true);

// 第二种模式4.2.0+可用
$ws->push(obj $data);

           
Swoole基础——04 Websocket定义使用websocket完整实例完整实例(oop)

$opcode:

  • 1 ,文本数据
  • 2 ,二进制数据

swoole_websocket_frame对象

Swoole基础——04 Websocket定义使用websocket完整实例完整实例(oop)

完整实例

<?php

//创建websocket服务器对象,监听0.0.0.0:8812端口
$ws = new swoole_websocket_server("0.0.0.0", 8812);


// 2.设置,如果访问静态资源,将不会走下面的逻辑
$ws->set([
	'enable_static_handler' => true,
	'document_root' => "/swoole/static"
]);


// 3.监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
	// 服务器端打印如下信息
	var_dump($request->fd, $request->get, $request->server);

	// 客户端输出如下信息
	$ws->push($request->fd, "客户端{$request->fd}连接服务器\n");
});

// 4.监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
	// 服务器端打印如下信息
	echo "收到来自客户端的信息:{$frame->data}\n";

	// 客户端输出如下信息
	$ws->push($frame->fd, "收到来自客户端的信息:{$frame->data}");
});

// 5.监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
	echo "客户端{$fd}断开连接\n";
});

// 5.启动服务器
$ws->start();

           

完整实例(oop)

<?php

class Ws
{   
	const HOST = "0.0.0.0";
	const PORT = 8812;
	public $ws = null;


	public function __construct(){
		// 1.创建websocket对象
		$this->ws = new swoole_websocket_server(self::HOST, self::PORT);

		// 2.设置,如果访问静态资源,将不会走下面的逻辑
		$this->ws->set([
			'enable_static_handler' => true,
			'document_root' => "/swoole/static"
		]);
        
		// 3.各种事件
		$this->ws->on("open",[$this,'onOpen']);
		$this->ws->on("message",[$this,'onMessage']);
		$this->ws->on("close",[$this,'onClose']);

		// 5.开启服务器
		$this->ws->start();
    }

    
	/**
	 * onOpen事件——监听WebSocket连接打开事件
	 * @param  $ws       websocket服务器对象
	 * @param  $request  Http请求对象
	 */
	public function onOpen($ws,$request){
		// 服务器打印客户端socket id
		echo "客户端id{$request->fd}连接服务器";
	}


	/**
	 * onMessage事件——监听WebSocket消息事件
	 * @param  $ws       websocket服务器对象
	 * @param  $frame    swoole_websocket_frame对象
	 */
	public function onMessage($ws,$frame){
		// 服务器打印如下信息
		echo "收到来自客户端{$frame->id}的数据:{$frame->data}\n";
        
		// 向客户端输出如下信息
		$ws->push($frame->fd, "ws服务器收到来自客户端{$frame->fd}的数据: {$frame->data}");
    }

	/**
	 * onClose事件——监听WebSocket连接关闭事件
	 * @param  $ws       websocket服务器对象
	 * @param  $fd       客户端socket id
	 */
	public function onClose($ws,$fd){
		// 服务器打印如下信息
		echo "客户端{$fd}断开连接\n";
	}
}

// 实例化
$obj = new Ws();