使用Swoole编写简单的Websocket服务器
作者: 何忠利 • 发表于 2017-04-12
首先要对 Swoole 有初步的认识,并且服务器得安装好Swoole扩展,这边就不过多介绍。
编译安装好后输入命令:
php -m | grep swoole
输出以下则安装成功!
swoole
服务端websocketserver.php代码如下
<?php
$redis = new redis();
$redis->connect("127.0.0.1",6379);
$server = new swoole_websocket_server("0.0.0.0", 9501);
$server->set(array(
'worker_num' => 4, //工作进程数量
'daemonize' => false, //是否作为守护进程
));
$server->on('open',function($server,$request){
global $redis;
$redis->sadd($request->cookie['group'],$request->fd);
$redis->hmset("hfd".$request->fd,array("username" => $request->cookie['username'] ,"group" => $request->cookie['group']));
$info = $redis->smembers($request->cookie['group']);
$obj = json_decode(substr(base64_decode($request->cookie['username']),0,-3));
foreach($redis->smembers("lixian".$request->cookie['group']) as $user){
if($user == $obj->user){
foreach($redis->lrange("xiaoxi".$request->cookie['group'],0,-1) as $message){
$server->push($request->fd,htmlspecialchars($message));
}
}
}
for($i = 1;$i < count($info);$i++){
$server->push($info[$i],$obj->user."加入聊天室");
}
});
$server->on('message',function($server,$request){
global $redis;
$info = $redis->hgetall('hfd'.$request->fd);
$obj = json_decode(substr(base64_decode($info['username']),0,-3));
foreach($redis->smembers($info['group']) as $id){
if($id != 0){
$server->push($id,$obj->user."说".htmlspecialchars($request->data));
}
}
$redis->rpush('xiaoxi'.$info['group'],$obj->user."说".$request->data);
});
$server->on('close',function($server,$request){
global $redis;
$info = $redis->hgetall("hfd".$request);
$obj = json_decode(substr(base64_decode($info['username']),0,-3));
foreach($redis->smembers($info['group']) as $id){
if($id != 0 && $id != $request){
$server->push($id,$obj->user."离开聊天室");
}
}
$redis->sadd('lixian'.$info['group'],$obj->user);
$redis->srem($info['group'],$request);
});
$server->start();
这边是利用了Redis集合数据类型实现的分组聊天,list实现离线消息推送。
接下来我们启动这个文件:
php websocketserver.php &
查看服务是否成功启动
ps aux | grep websocketserver.php
如果看到有进程在启动则成功!!!
客户端client.php代码如下:
<?php
session_start();
if(!isset($_COOKIE['username']))
{
header("location:http://www.hezhongli.cn/login.html");
}
if(!isset($_COOKIE['group'])){
header("location:http://www.hezhongli.cn/list.php");
}
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
<script typet="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
<script type='text/javascript'>
function scrollToBottom(){
$("#content").scrollTop(100000000000);
}
</script>
<script type="text/javascript">
if(window.WebSocket){
var webSocket = new WebSocket("ws://www.hezhongli.cn:9501");
webSocket.onopen = function (event) {
};
webSocket.onmessage = function (event) {
var content = document.getElementById('content');
content.innerHTML = content.innerHTML.concat('<p style="margin-left:20px;height:20px;line-height:20px;">'+event.data+'</p>');
scrollToBottom();
}
var sendMessage = function(){
var data = document.getElementById('message').value ;
webSocket.send(data);
document.getElementById('message').value = '';
}
webSocket.onclose = function (event) {
var cookie = document.cookie;
var str = cookie.match(/username=(\S*)/)[1];
webSocket.send(str);
}
}else{
console.log("您的浏览器不支持WebSocket");
}
</script>
</head>
<body>
<center><a href="http://www.hezhongli.cn/list.php"> 退出聊天室</a></center>
<div style="width:600px;margin:0 auto;border:1px solid #ccc;">
<div id="content" style="overflow-y:auto;height:300px;"></div>
<hr/>
<div style="height:40px">
<input type="text" id="message" style="margin-left:10px;height:25px;width:450px;">
<button onclick="sendMessage()" style="height:28px;width:75px;">发送</button>
</div>
</div>
</body>
</html>
这边就可以正常测试了。
可能会遇见的问题:
查看自己端口是否开放可用 telnet 命令测试
我这边cookie简单的base64转化用户信息,真实环境中一定得加密!!!
文章关键词:
# 即时通讯
# Websocket协议
# PHP扩展Swoole
阅读量:
999
返回主页