前言:我得了-> 不写日记就学习不下去的病。
我们将用到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 = 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, 简易聊天系统完成。
网友评论