基于 Swoole 构建高性能 Laravel 应用系列 —— 基于 Swoole 实现简单的 WebSocket 服务器

栏目: PHP · 发布时间: 5年前

内容简介:这篇教程取自在此之前,有必要对 WebSocket 的原理做简单的说明,WebSocket 复用了 HTTP 协议来实现握手,然后通过请求报文中的 Upgrade 字段将 HTTP 协议升级到 WebSocket 协议来建立 WebSocket 通信连接,一旦 WebSocket 连接建立之后,就可以在这个长连接上通过 WebSocket 数据帧进行双向通信,客户端和服务端可以在任何时候向对方发送报文,而不是 HTTP 协议那种服务端只有在客户端发起请求后才能响应,从而解决了在 Web 页面实时显示最新资源

WebSocket 概述

这篇教程取自 社群分享 程序员 内功修炼系列网络协议篇 ,其中对 WebSocket 协议的由来、实现原理和通信演示有详细介绍,这里我们摘取其中的简单实现篇来介绍,因为在那里也是基于 Swoole 实现 WebSocket 服务器的。

在此之前,有必要对 WebSocket 的原理做简单的说明,WebSocket 复用了 HTTP 协议来实现握手,然后通过请求报文中的 Upgrade 字段将 HTTP 协议升级到 WebSocket 协议来建立 WebSocket 通信连接,一旦 WebSocket 连接建立之后,就可以在这个长连接上通过 WebSocket 数据帧进行双向通信,客户端和服务端可以在任何时候向对方发送报文,而不是 HTTP 协议那种服务端只有在客户端发起请求后才能响应,从而解决了在 Web 页面实时显示最新资源的问题。

与 HTTP 类似,WebSocket 协议对应的 scheme 是 ws ,如果是加密的 WebSocket 对应的 scheme 是 wss

在这篇教程中,学院君将在服务端基于 Swoole 实现简单的 WebSocket 服务器,然后在客户端基于 JavaScript 实现 WebSocket 客户端。

WebSocket 服务器

PHP 异步网络通信引擎 Swoole 内置了对 WebSocket 的支持,通过几行 PHP 代码就可以写出一个异步非阻塞多进程的 WebSocket 服务器:

<?php
// 初始化 WebSocket 服务器,在本地监听 8000 端口
$server = new Swoole\WebSocket\Server("localhost", 8000);

// 建立连接时触发
$server->on('open', function (Swoole\WebSocket\Server $server, $request) {
    echo "server: handshake success with fd{$request->fd}\n";
});

// 收到消息时触发推送
$server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
    echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
    $server->push($frame->fd, "this is server");
});

// 关闭 WebSocket 连接时触发
$server->on('close', function ($ser, $fd) {
    echo "client {$fd} closed\n";
});

// 启动 WebSocket 服务器
$server->start();

编写完成后,将这段 PHP 代码保存到本地 websocket_server.php 文件。

WebSocket 客户端

在客户端,可以通过 JavaScript 调用浏览器内置的 WebSocket API 实现 WebSocket 客户端,实现代码和服务端差不多,无论服务端还是客户端 WebSocket 都是通过事件驱动的,我们在一个 HTML 文档中引入相应的 JavaScript 代码:

<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   <title>Chat Client</title>
</head>
<body>
<script>
   window.onload = function () {
       var nick = prompt("Enter your nickname");
       var input = document.getElementById("input");
       input.focus();

       // 初始化客户端套接字并建立连接
       var socket = new WebSocket("ws://localhost:8000");

       // 连接建立时触发
       socket.onopen = function (event) {
           console.log("Connection open ..."); 
       }

       // 接收到服务端推送时执行
       socket.onmessage = function (event) {
           var msg = event.data;
           var node = document.createTextNode(msg);
           var div = document.createElement("div");
           div.appendChild(node);
           document.body.insertBefore(div, input);
           input.scrollIntoView();
       };

       // 连接关闭时触发
       socket.onclose = function (event) {
           console.log("Connection closed ..."); 
       }

       input.onchange = function () {
           var msg = nick + ": " + input.value;
           // 将输入框变更信息通过 send 方法发送到服务器
           socket.send(msg);
           input.value = "";
       };
   }
</script>
<input id="input" style="width: 100%;">
</body>
</html>

将这个 HTML 文档命名为 websocket_client.html

WebSocket 通信演示

接下来,我们在命令行启动 WebSocket 服务器:

php websocket.php

然后在浏览器中访问 websocket_client.html ,首先会提示我们输入昵称:

基于 Swoole 构建高性能  <a href='https://www.codercto.com/topics/5169.html'>Laravel</a>  应用系列 —— 基于 Swoole 实现简单的 WebSocket 服务器

输入之后点击确定,JavaScript 代码会继续往下执行,让输入框获取焦点,然后初始化 WebSocket 客户端并连接到服务器,这个时候通过开发者 工具 可以看到 Console 标签页已经输出了连接已建立日志:

基于 Swoole 构建高性能 Laravel 应用系列 —— 基于 Swoole 实现简单的 WebSocket 服务器

在 Network 里面也可以看到 WebSocket 握手请求和响应:

基于 Swoole 构建高性能 Laravel 应用系列 —— 基于 Swoole 实现简单的 WebSocket 服务器

这个时候我们在输入框中输入「你好,WebSocket!」并回车,即可触发客户端发送该数据到服务器,服务器接收到消息后会将其显示出来:

基于 Swoole 构建高性能 Laravel 应用系列 —— 基于 Swoole 实现简单的 WebSocket 服务器

同时将「This is server」消息推送给客户端,客户端通过 onmessage 回调函数将获取到的数据显示出来。在开发者工具的 Network->WS 标签页可以查看 WebSocket 通信细节:

基于 Swoole 构建高性能 Laravel 应用系列 —— 基于 Swoole 实现简单的 WebSocket 服务器

看起来,这个过程还是客户端触发服务器执行推送操作,但实际上,在建立连接并获取到这个客户端的唯一标识后,后续服务端资源有更新的情况下,仍然可以通过这个标识主动将更新推送给客户端,而不需要客户端发起拉取请求。WebSocket 服务器和客户端在实际项目中的实现可能会更加复杂,但是基本原理是一致的。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机算法导引

计算机算法导引

卢开澄 / 第2版 (2006年1月1日) / 2006-1 / 38.0

本书为《计算机算法导引——设计与分析》的第2版。书中内容分3部分:第1部分是基本算法,按方法论区分,包含优先策略与分治策略、动态规划、概率算法、并行算法、搜索法、数据结构等;第2部分是若干专题,包括排序算法、计算几何及计算数论、线性规划;第3部分是复杂性理论与智能型算法,其中,智能型算法主要介绍了遗传算法和模拟退火算法。本书可作为计算机系本科学生及研究生教材,数学系师生和科研T作者也可将其作为参考......一起来看看 《计算机算法导引》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具