美文网首页
workerman 搭建简易聊天系统

workerman 搭建简易聊天系统

作者: 蛐蛐儿阳 | 来源:发表于2020-03-21 17:15 被阅读0次

    前言:我得了-> 不写日记就学习不下去的病。
    我们将用到docker, php7.4, GatewayWorker, VUE, axios。除了php都是新东西,想巩固一下学习内容。
    下载和安装php扩展这里不说了,直接上下测试代码。
    php代码

    <?php
    use Workerman\Worker;
    require_once __DIR__ . '/Workerman/Autoloader.php';
    
    // 注意:这里与上个例子不同,使用的是websocket协议
    $ws_worker = new Worker("websocket://0.0.0.0:2001");
    
    // 启动4个进程对外提供服务
    $ws_worker->count = 4;
    
    // 当收到客户端发来的数据后返回hello $data给客户端
    $ws_worker->onMessage = function($connection, $data)
    {
        // 向客户端发送hello $data
        $connection->send('hello ' . $data);
    };
    
    // 运行worker
    Worker::runAll();
    

    启动此脚本

    php webSocket.php start
    

    js代码,直接放html里面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <script>
        ws = new WebSocket("ws://127.0.0.1:2001");
        ws.onopen = function() {
            alert("连接成功");
            ws.send('tom');
            alert("给服务端发送一个字符串:tom");
        };
        ws.onmessage = function(e) {
            alert("收到服务端的消息:" + e.data);
        };
    </script>
    </body>
    </html>
    

    打开此页面,看到几个alert信息了,证明链接成功。
    此时我们还只是停留在书中的例子,现在用下GatewayWorker。下面是手册地址。
    http://doc2.workerman.net/

    socket通信用不着axios, 正好复习下vue,html代码

    <div id="app">
    {{message}}
    <input type="button" @click="log" value="发送"/>
    </div>
    js代码
    new Vue({
        el: '#app',
        data () {
            return {
                message: ''
            }
        },
        methods: {
        log:function(event) {
            alert('你好');
        }}
    });
    

    这里用hbuilder编写前端,phpIDE报错。socket配合VUE这么使用

    new Vue({
        el: '#app',
        data () {
            return {
                send_message: '',
                get_message : '',
                socket:"",
                path:"ws://127.0.0.1:2001",
            }
        },
        mounted () {
            // 初始化
            this.init()
        },
        methods: {
        init: function () {
                if(typeof(WebSocket) === "undefined"){
                    alert("您的浏览器不支持socket")
                }else{
                    // 实例化socket
                    this.socket = new WebSocket(this.path)
                    // 监听socket连接
                    this.socket.onopen = this.open
                    // 监听socket错误信息
                    this.socket.onerror = this.error
                    // 监听socket消息
                    this.socket.onmessage = this.getMessage
                }
            },
        log:function(event) {
            this.socket.send(this.send_message);
        },
    
        getMessage: function (msg) {
            this.get_message = msg.data
        },
        }
    });
    

    这里注意下, this.socket.send和getMessage区别。
    然后是php代码

    <?php
    use Workerman\Worker;
    require_once __DIR__ . '/Workerman/Autoloader.php';
    
    // 注意:这里与上个例子不同,使用的是websocket协议
    $ws_worker = new Worker("websocket://0.0.0.0:2001");
    
    // 启动4个进程对外提供服务
    $ws_worker->count = 4;
    
    // 当收到客户端发来的数据后返回hello $data给客户端
    $ws_worker->onMessage = function($connection, $data)
    {
        // 向客户端发送hello $data
        var_dump($data);
        $connection->send($data);
    };
    
    // 运行worker
    Worker::runAll();
    

    至此,可以发送,并接收信息了,但如果两个用户,A用户看不到B用户的信息。
    workerman所谓群发功能

    // 当收到客户端发来的数据后返回hello $data给客户端
    $ws_worker->onMessage = function($connection, $data)
    {
        global $ws_worker   ;
        foreach($ws_worker->connections as $connection) {
            $connection->send($data);
        }
    };
    

    通了,下面的代码是,如何利用VUE实现类似jq 的appendto,添加元素功能。
    php代码不变,js代码改成下面这样

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <script src="js/vue.js"></script>
    
    <body>
    <div id="app">
        <li v-for="message in get_message">
          {{ message }}
        </li>
      </ol>
    <input type="text" v-model="send_message">
    <input type="button" @click="log" value="发送"/>
    </div>
    <script>
    
    new Vue({
        el: '#app',
        data () {
            return {
                send_message: '',
                get_message : [1,2],
                socket:"",
                path:"ws://127.0.0.1:2001",
            }
        },
        mounted () {
            // 初始化
            this.init()
        },
        methods: {
        init: function () {
                if(typeof(WebSocket) === "undefined"){
                    alert("您的浏览器不支持socket")
                }else{
                    // 实例化socket
                    this.socket = new WebSocket(this.path)
                    // 监听socket连接
                    this.socket.onopen = this.open
                    // 监听socket错误信息
                    this.socket.onerror = this.error
                    // 监听socket消息
                    this.socket.onmessage = this.getMessage
                }
            },
        log:function(event) {
            this.socket.send(this.send_message);
        },
    
        getMessage: function (msg) {
            //this.get_message = msg.data
            this.get_message.push(msg.data)
        },
        }
    });
    </script>
    </body>
    </html>
    

    主要把数组push出去。
    时好时坏,退出后,有的客户端只能收到自己的信息。我把php中ws_worker->count = 4;改成ws_worker->count = 1;, 开四个用户,四个用户都能接收到信息了。

    ok, 到最后这篇文章还是折腾了我们两天, 最后我们就只有两个文件,通信是经过我们ip和端口,就是socket协议进行通信的,所以文件名不重要,我们看webSocket.php最后代码

    <?php
    use Workerman\Worker;
    require_once __DIR__ . '/Workerman/Autoloader.php';
    
    // 注意:这里与上个例子不同,使用的是websocket协议
    $ws_worker = new Worker("websocket://0.0.0.0:2001");
    
    // 启动4个进程对外提供服务
    $ws_worker->count = 1;
    
    // 当收到客户端发来的数据后返回hello $data给客户端
    $ws_worker->onMessage = function($connection, $data)use($ws_worker)
    {
    //    var_dump($ws_worker->connections);
        foreach($ws_worker->connections as $connection) {
            $connection->send($data);
        }
    };
    
    // 运行worker
    Worker::runAll();
    

    就是文档里的代码,修改部分是里面加了个foreach,我们要获取所有连接。然后

    #后台启动
    php webSocket.php start -d
    

    前端代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <script src="js/vue.js"></script>
    
    <body>
    <div id="app">
        <li v-for="message in get_message">
          {{ message }}
        </li>
      </ol>
    <input type="text" v-model="send_message">
    <input type="button" @click="log" value="发送"/>
    </div>
    <script>
    
    new Vue({
        el: '#app',
        data () {
            return {
                send_message: '',
                get_message : [],
                socket:"",
                path:"ws://127.0.0.1:2001",
            }
        },
        mounted () {
            // 初始化
            this.init()
        },
        methods: {
        init: function () {
                if(typeof(WebSocket) === "undefined"){
                    alert("您的浏览器不支持socket")
                }else{
                    // 实例化socket
                    this.socket = new WebSocket(this.path)
                    // 监听socket连接
                    this.socket.onopen = this.open
                    // 监听socket错误信息
                    this.socket.onerror = this.error
                    // 监听socket消息
                    this.socket.onmessage = this.getMessage
                }
            },
        log:function(event) {
            this.socket.send(this.send_message);
        },
    
        getMessage: function (msg) {
            //this.get_message = msg.data
            this.get_message.push(msg.data)
        },
        }
    });
    </script>
    </body>
    </html>
    
    // 这一波代码学到的是
    // 1,  getMessage,  是所有用户都需要后端发送的信息, 而不是放 log里面,点击后才接受信息。
    // 2, 是否用this.get_message.pus有待商榷,如果用,v-for里面肯定要添加v-if,  来判断显示样式。(一般是判断谁说的话,显示在那一边)
    

    ok, 简易聊天系统完成。

    相关文章

      网友评论

          本文标题:workerman 搭建简易聊天系统

          本文链接:https://www.haomeiwen.com/subject/hpmjyhtx.html