前期准备
- 安装php和swoole扩展
- 安装redis和php redis扩展
利用php的swoole扩展可以轻松搭建websocket服务器,当然了解网络编程和websocket协议的童鞋也可以自己写一个websocket服务器。这里利用redis处理消息队列。
后端代码文件WebsocketClient.php:
<?php
class WebsocketClient {
public $server;
public function __construct() {
$this->server = new Swoole\WebSocket\Server("0.0.0.0", 9501);
$this->server->on('open', function (swoole_websocket_server $server, $request) {
});
$this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
$message = explode(':', trim($frame->data));
$redis = new \Redis;
$redis->connect('127.0.0.1',6379);
//初始连接,接收消息
if($message[2]==='connect'){
$server->push($frame->fd,'系统消息:连接已建立......');
$msg_array = $redis->lRange("msg_by_".$message[1],0,-1);
foreach ($msg_array as $key => $value) {
$server->push($request->fd,$value);
}
$redis->set($message[0],$frame->fd);
$redis->set($frame->fd,$message[0]);
$redis->delete("msg_by_".$message[1]);
return;
}
//发送消息,对方在线则发送
if($to = $redis->get($message[1])){
$server->push($to, $message[2]);
}else{
$redis->rPush("msg_by_".$message[1],$message[2]);
}
});
$this->server->on('close', function ($ser, $fd) {
$redis = new \Redis;
$redis->connect('127.0.0.1',6379);
$name = $redis->get($fd);
$redis->delete($name,$fd);
});
$this->server->on('request', function ($request, $response) {
// 接收http请求从get获取message参数的值,给用户推送
// $this->server->connections 遍历所有websocket连接用户的fd,给所有用户推送
foreach ($this->server->connections as $fd) {
// 需要先判断是否是正确的websocket连接,否则有可能会push失败
if ($this->server->isEstablished($fd)) {
$this->server->push($fd, $request->get['message']);
}
}
});
$this->server->start();
}
}
new WebsocketClient();
在命令行运行 php WebsocketClient.php,启动websocket服务器。然后新建两个静态页面来测试,
socket_client.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chat Online</title>
<script type="text/javascript">
window.onload = function(){
var sender = "xiaoming";
var receiver = 'dachun';
var input = document.getElementById("input");
input.focus();
var f = 0;//标识当前消息的发送者
//打开一个websocket
var socket = new WebSocket("ws://192.168.33.10:9501");
socket.onopen = function(){
socket.send("xiaoming:dachun:connect");
};
//从服务器获取消息
socket.onmessage = function(event){
var msg = event.data;
if(f!==2)
{
var node = document.createTextNode(receiver);
var div = document.createElement('div');
div.style.backgroundColor = '#B0B0B0';
div.style.color = 'red';
div.style.textAlign = 'right';
div.appendChild(node);
document.body.insertBefore(div,input);
}
var node = document.createTextNode(msg);
var div = document.createElement('div');
div.style.color = 'blue';
div.style.padding = "10px";
div.style.textAlign = 'right';
div.appendChild(node);
document.body.insertBefore(div,input);
input.scrollIntoView();
f=2;
};
//发送消息给服务器
input.onchange = function(){
var msg = sender + ":" + receiver + ":"+input.value;
if(f!==1){
var node = document.createTextNode(sender);
var div = document.createElement('div');
div.style.backgroundColor = '#9933CC';
div.style.textAlign = 'left';
div.style.color = 'black';
div.appendChild(node);
document.body.insertBefore(div,input);
}
var node = document.createTextNode(input.value);
var div = document.createElement('div');
div.style.color = 'gray';
div.style.textAlign = 'left';
div.style.padding = "10px";
div.appendChild(node);
document.body.insertBefore(div,input);
socket.send(msg);
input.value = "";
f=1;
};
};
</script>
</head>
<body>
<div></div>
<input type="" name="" id="input" style="width: 100%;">
<!-- <button οnclick="sendMessage()">提交</button> -->
</body>
</html>
第二个文件和第一个文件一样,不同的是sender和receiver,socket_client2.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chat Online</title>
<script type="text/javascript">
window.onload = function(){
var sender = "dachun";
var receiver = 'xiaoming';
var input = document.getElementById("input");
input.focus();
var f = 0;
//打开一个websocket
var socket = new WebSocket("ws://192.168.33.10:9501");
socket.onopen = function(){
socket.send("dachun:xiaoming:connect");
};
//从服务器获取消息
socket.onmessage = function(event){
var msg = event.data;
if(f!==2)
{
var node = document.createTextNode(receiver);
var div = document.createElement('div');
div.style.backgroundColor = '#B0B0B0';
div.style.color = 'red';
div.style.textAlign = 'right';
div.appendChild(node);
document.body.insertBefore(div,input);
}
var node = document.createTextNode(msg);
var div = document.createElement('div');
div.style.color = 'blue';
div.style.padding = "10px";
div.style.textAlign = 'right';
div.appendChild(node);
document.body.insertBefore(div,input);
input.scrollIntoView();
f=2;
};
//发送消息给服务器
input.onchange = function(){
var msg = sender + ":" + receiver + ":"+input.value;
if(f!==1){
var node = document.createTextNode(sender);
var div = document.createElement('div');
div.style.backgroundColor = '#9933CC';
div.style.textAlign = 'left';
div.style.color = 'black';
div.appendChild(node);
document.body.insertBefore(div,input);
}
var node = document.createTextNode(input.value);
var div = document.createElement('div');
div.style.color = 'gray';
div.style.textAlign = 'left';
div.style.padding = "10px";
div.appendChild(node);
document.body.insertBefore(div,input);
socket.send(msg);
input.value = "";
f=1;
};
};
</script>
</head>
<body>
<div></div>
<input type="" name="" id="input" style="width: 100%;">
<!-- <button οnclick="sendMessage()">提交</button> -->
</body>
</html>
之后在浏览器打开 socket_client.html 和 socket_client2.html,测试发送: