Laravel8使用laravel-s实现WebSocket服务器
Laravel8使用laravel-s实现WebSocket服务器.通过 详解基于Laravel8下的LaravelS实现高性能HTTP服务器 我们安装了LaravelS并实现了一个HTTP服务器,那么本篇文章在此基础上在实现一个Websocket服务器。
创建WebSocketService类
创建WebSocketService
类并实现Hhxsv5\LaravelS\Swoole\WebSocketHandlerInterface
类。
文件位置:app/Services/WebSocketService.php
- <?php
- namespace App\Services;
- use Hhxsv5\LaravelS\Swoole\WebSocketHandlerInterface;
- use Swoole\Http\Request;
- use Swoole\Http\Response;
- use Swoole\WebSocket\Frame;
- use Swoole\WebSocket\Server;
- use Illuminate\Support\Facades\Log;
- /**
- * @see https://wiki.swoole.com/#/start/start_ws_server
- */
- class WebSocketService implements WebSocketHandlerInterface
- {
- // 声明没有参数的构造函数
- public function __construct()
- {
- }
- public function onOpen(Server $server, Request $request)
- {
- // 在触发onOpen事件之前,建立WebSocket的HTTP请求已经经过了Laravel的路由,
- // 所以Laravel的Request、Auth等信息是可读的,Session是可读写的,但仅限在onOpen事件中。
- // \Log::info('New WebSocket connection', [$request->fd, request()->all(), session()->getId(), session('xxx'), session(['yyy' => time()])]);
- // 此处抛出的异常会被上层捕获并记录到Swoole日志,开发者需要手动try/catch
- Log::info('WebSocket 建立连接');
- $server->push($request->fd, 'Welcome to LaravelS');
- }
- public function onMessage(Server $server, Frame $frame)
- {
- // \Log::info('Received message', [$frame->fd, $frame->data, $frame->opcode, $frame->finish]);
- // 此处抛出的异常会被上层捕获并记录到Swoole日志,开发者需要手动try/catch
- $server->push($frame->fd, date('Y-m-d H:i:s'));
- }
- public function onClose(Server $server, $fd, $reactorId)
- {
- Log::info('websocket 关闭');
- }
- }
修改配置文件
文件位置:app/config/laravels.php
- 'websocket' => [
- 'enable' => true, // 注意:设置enable为true
- 'handler' => \App\Services\WebSocketService::class,
- ],
- 'swoole' => [
- //...
- // dispatch_mode只能设置为2、4、5,https://wiki.swoole.com/#/server/setting?id=dispatch_mode
- 'dispatch_mode' => 2,
- //...
- ],
修改nginx配置文件
文件位置:/usr/local/nginx/conf/vhosts/laravel_s.conf
- map $http_upgrade $connection_upgrade {
- default upgrade;
- '' close;
- }
- upstream laravels {
- # 此处注意,我使用的是Linux系统环境,因此这里使用的是Linux中的IP地址
- # 由于默认是127.0.0.1,或是在Linux中可能会导致websocket无法完成服务
- server 192.168.133.131:5200 weight=5 max_fails=3 fail_timeout=30s;
- keepalive 16;
- }
- server {
- listen 80;
- server_name laravel-s.com;
- root /www/laravel_swoole/public;
- index index.php index.html index.htm;
- location / {
- try_files $uri @laravels;
- }
- # 配置websockeet
- location = /ws {
- proxy_http_version 1.1;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Real-PORT $remote_port;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Host $http_host;
- proxy_set_header Scheme $scheme;
- proxy_set_header Server-Protocol $server_protocol;
- proxy_set_header Server-Name $server_name;
- proxy_set_header Server-Addr $server_addr;
- proxy_set_header Server-Port $server_port;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection $connection_upgrade;
- proxy_pass http://laravels;
- }
- # 配置laravels
- location @laravels {
- proxy_http_version 1.1;
- proxy_set_header Connection "";
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Real-PORT $remote_port;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Host $http_host;
- proxy_set_header Scheme $scheme;
- proxy_set_header Server-Protocol $server_protocol;
- proxy_set_header Server-Name $server_name;
- proxy_set_header Server-Addr $server_addr;
- proxy_set_header Server-Port $server_port;
- proxy_pass http://laravels;
- }
- }
注意:laravels配置中的server需要填写本机IP。由于我使用的是Linux系统,因此配置了Linux系统中的IP。
配置.env文件
- LARAVELS_LISTEN_IP=192.168.133.131
- LARAVELS_DAEMONIZE=true
LARAVELS_LISTEN_IP要与upstream laravels配置的IP一样
启动laravels
切换到应用根目录,启动laravels
- php bin/laravels start
重启nginx服务器
- systemctl restart nginx.service
编写前端界面
testSwoole.html,此界面位于windows
- <!DOCTYPE html>
- <html>
- <head>
- <title></title>
- </head>
- <body>
- <input id="input" style="width: 100%;" >
- <script>
- window.onload = function() {
- let nick = prompt('Enter your nickname');
- let input = document.getElementById('input');
- input.focus();
- // 初始化客户端套接字并建立连接
- let socket = new WebSocket("ws://laravel-s.com/ws");
- // 建立连接时触发
- socket.onopen = function(event) {
- console.log('连接开始...');
- }
- // 接收到服务器信息
- socket.onmessage = function(event) {
- let msg = event.data;
- let node = document.createTextNode(msg);
- let div = document.createElement('div');
- div.appendChild(node);
- document.body.insertBefore(div,input);
- input.scrollIntoView();
- }
- // 关闭连接时触发
- socket.onclose = function(event) {
- console.log('连接关闭...');
- }
- input.onchange = function() {
- let msg = nick + ": " + input.value;
- socket.send(msg);
- input.value="";
- }
- }
- </script>
- </body>
- </html>
尤其注意 let socket = new WebSocket("ws://laravel-s.com/ws"); 此时已经变成域名,默认80端口。当访问此页面并输入信息后,客户端发起协议升级请求后将信息发送到指定地址
打开该html页面并输入信息后查看websocket通信请求过程,可以看到协议已经升级为websocket
- # 通用头
- General
- Request URL: ws://laravel-s.com/ws
- Request Method: GET
- Status Code: 101 Switching Protocols
- # 响应头
- Connection: upgrade
- Date: Wed, 10 Mar 2021 16:39:21 GMT
- Sec-Websocket-Version: 13
- Upgrade: websocket
- # 通用头
- Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
- Sec-WebSocket-Key: LeAIasPj2v1aK4TKw0QqsA==
- Sec-WebSocket-Version: 13
- Upgrade: websocket
关于报错
刚编写完成并运行时,websocket客户端(也就是浏览器运行的testSwoole.html)出现failed: Error during WebSocket handshake: Unexpected response code: 404
错误,这个错误如何解决?都知道404为页面错误,根据这个我仔细检查了代码,没有错误,下面来说说我的解决方法吧, 虽然有些不知所以然。
解决方法
1)重启 laravels
2)重启nginx
我就是这样解决了这个错误,如何你也遇到同样的问题,欢迎一起交流学习。
本文网址:https://www.zztuku.com/index.php/detail-13792.html
站长图库 - Laravel8使用laravel-s实现WebSocket服务器
申明:本文转载于《自如初博客》,如有侵犯,请 联系我们 删除。
您还没有登录,请 登录 后发表评论!
提示:请勿发布广告垃圾评论,否则封号处理!!