美文网首页
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