PHP学习进阶之swoole,使用websocket制作一个简单的聊天室 - 唐轶俊博客

PHP学习进阶之swoole,使用websocket制作一个简单的聊天室

PHP 1085浏览 评论

前面历经99重磨难,取得震惊...

要想修成正果....

少年,革命尚未成功同志还需努力...

在前面2章我们主要讲解如何swoole运行环境,接下来我们就写一个简单的案例来使用一下传说中的swoole,看看此技到底多厉害。

swoole学习之第一式:websoket之聊天室

简单的分析下做一个聊天室,需要干什么?

1、首先要有一台websoket服务器

2、使用WebSocket协议与服务器进行通信

官网文档上简单的说了流程,引用一下:

WebSocket服务器是建立在Http服务器之上的长连接服务器,客户端首先会发送一个Http的请求与服务器进行握手。握手成功后会触发onOpen事件,表示连接已就绪,onOpen函数中可以得到$request对象,包含了Http握手的相关信息,如GET参数、Cookie、Http头信息等。

建立连接后客户端与服务器端就可以双向通信了。

  • 客户端向服务器端发送信息时,服务器端触发onMessage事件回调

  • 服务器端可以调用$server->push()向某个客户端(使用$fd标识符)发送消息

  • 服务器端可以设置onHandShake事件回调来手工处理WebSocket握手

简单总结下:客户端链接服务器

1、首先有握手信号标识是否成功,成功之后调用回调函数,onOpen,这个是可以不设置的,一般用作于欢迎信息。通常大家看到的欢迎谁谁谁来到聊天室就是这个了,链接成功除服onOpen 此时我们服务端推送一条消息给客户端。

函数官网解释入下

function onOpen(swoole_websocket_server $svr, swoole_http_request $req);
  • $req 是一个Http请求对象,包含了客户端发来的握手请求信息

  • onOpen事件函数中可以调用push向客户端发送数据或者调用close关闭连接

  • onOpen事件回调是可选的



2、当服务器收到来自客户端的数据帧时会回调onMessage函数,客户端发来数据,我们再此函数来将数据广播出去就形成了聊天,经过各种处理形成一个成型的聊天室。

函数官网解释入下

function onMessage(swoole_server $server, swoole_websocket_frame $frame)
  • $frame 是swoole_websocket_frame对象,包含了客户端发来的数据帧信息

  • onMessage回调必须被设置,未设置服务器将无法启动

  • 客户端发送的ping帧不会触发onMessage,底层会自动回复pong包

3、在onMessage如何发送数据?使用push向websocket客户端连接推送数据,长度最大不得超过2M

向websocket客户端连接推送数据,长度最大不得超过2M。

function swoole_websocket_server->push(int $fd, string $data, int $opcode = 1, bool $finish = true);
  • $fd 客户端连接的ID,如果指定的$fd对应的TCP连接并非websocket客户端,将会发送失败

  • $data 要发送的数据内容

  • $opcode,指定发送数据内容的格式,默认为文本。发送二进制内容$opcode参数需要设置为WEBSOCKET_OPCODE_BINARY

  • 发送成功返回true,发送失败返回false

swoole_websocket_server->push在swoole-1.7.11以上版本可用




通过上面的介绍,可以说做一个聊天室是非常的简单了,接下来我们就可以动手了:

  1. 我们搭建好的环境,apache默认项目目录是/data/wwwroot/default

  2. 我们在此目录下建一个web_server.php作为socket服务器,文件内容入下


<?php
// +----------------------------------------------------------------------
// | Created by  PhpStorm.
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 www.phpbloger.com.
// +----------------------------------------------------------------------
// | Create Time (2018/4/10-17:11)
// +----------------------------------------------------------------------
// | Author: 唐轶俊 <tangyijun@km.com>
// +----------------------------------------------------------------------
// | swoole websocket server
// +----------------------------------------------------------------------
$server = new swoole_websocket_server("0.0.0.0", 9501);
$server->set(array(
    'reactor_num' => 2,
    'worker_num' => 4,
    'backlog' => 128,
    'max_request' => 100,
    'dispatch_mode' => 1,
    'max_conn '   => 10000,
    'daemonize ' => 1,//守护进程话
    'open_cpu_affinity ' => 1,
    'heartbeat_check_interval ' => 30
));
$server->on('open', function (swoole_websocket_server $server, $request) {
    $server->push($request->fd, '欢迎来到聊天室');
});
$server->on('message', function (swoole_websocket_server $server, $frame) {
    //拆分数据
    $data = explode('|',$frame->data);
    foreach ($server->connections  as $fd){
        $server->push($fd, '用户'.$data[0].'说:'.$data[1]);
    }
});
$server->on('close', function($server, $fd) {
    echo "connection close: {$fd}\n";
});

$server->start();

3.cli下启动服务

php /data/wwwroot/default/web_server.php


4.前端搭建一个客户端(client)链接服务器进行通讯,代码入下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<style>
#message{ border: 1px solid #ccc; width: 100%; height: 200px;overflow: auto;}
#conent{ width: 100%; height: 50px; border: 1px solid #ccc;}
.main{margin-top: 10px;}
#sendMessage{ width: 100%; border: 1px solid #ccc; background: blue; color: #fff; padding: 10px; font-weight: bold; font-size: 16px;}
</style>
<div>
    <h1>聊天室</h1>
    <div id="message">

    </div>
    <div class="main">
        <textarea id="conent"></textarea>
        <button id="sendMessage" onclick="sendMessage()">发送消息</button>
    </div>
</div>
<script src="jquery-3.3.1.min.js"></script>
<script>
    var username = 'user_'+Math.random();
    var wsServer = 'ws://192.168.245.128:9501';
    var websocket = new WebSocket(wsServer);
    websocket.onopen = function (evt) {
        console.log("Connected to WebSocket server.");
    };
    websocket.onclose = function (evt) {
        console.log("Disconnected");
    };
    function sendMessage(){
        var content  =  document.getElementById('conent').value;
        if(content == ''){
            alert('请输入聊天内容');
            return;
        }
        //|作为数据包分割线
 var text = username+'|'+content;
        websocket.send(text);
    }
    //监听服务端回推的消息
 websocket.onmessage = function (evt) {
        var message = evt.data;
        var html = '<p>'+message+'</p>';
       $("#message").append(html);
       //成功将发送置空
 document.getElementById("conent").value = "";
    };
    websocket.onerror = function (evt, e) {
        console.log('Error occured: ' + evt.data);
    };
</script>
</body>
</html>

就这样一个简单的聊天室就搭建成功了。

我们看下效果,访问时,已经出现欢迎文字

同事开三个浏览器窗口

image.png


我们在窗口一发一条消息:

image.png

在2窗口和三窗口看效果

image.png



image.png

这样一个简陋的聊天室就搭建成功了

本文连接:http://www.phpbloger.com/article/58.html 文章都为原创,转载请注明出处!

相关文章