workerman聊天室

穷人什么苦都能吃就是吃不了学习的苦.
### 客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
// 创建一个Socket实例
var socket =null;//初始是null
var isLogin=false;//是否登录到服务器上

function send()
{
if(!isLogin)
{
alert("请先服务器验证");
return;
}
var msg=document.getElementById("txtmsg").value;
socket.send("msg:"+msg);
//在div 中显示我们的行为
var p=document.createElement("P");
p.innerHTML="<span>发送消息</span>"+msg
document.getElementById("txtcontent").appendChild(p);
}
function connectServer()
{
var userName=document.getElementById("username").value;
if(userName=="")
{
alert("用户昵称必填 ");
return;
}
socket=new WebSocket('ws://121.42.176.99:9091/');
// 打开Socket
socket.onopen = function(event) {
socket.send("login:"+userName);
};
socket.onmessage = function(event) {

var getMsg=event.data;
if(/^notice:success$/.test(getMsg)) //服务器验证通过,后面做任何发送操作
{
isLogin=true;
}
else if(/^msg:/.test(getMsg)) //代表是普通消息
{
//<p>xxxxooo</p>
var p=document.createElement("P");
p.innerHTML="<span>收到消息</span>"+getMsg.replace("msg:","");
document.getElementById("txtcontent").appendChild(p);
}
else if(/^users:/.test(getMsg))
{//显示当前已登录用户
getMsg=getMsg.replace("users:","");
getMsg=eval("("+getMsg+")");
document.getElementById("listusers").innerHTML="";
for(var key in getMsg)
{
var option=document.createElement("OPTION");
option.value=key;//IP
option.innerHTML=getMsg[key];//昵称
document.getElementById("listusers").appendChild(option);
}
}
else
{

}
};
// 监听Socket的关闭
socket.onclose = function(event) {
isLogin=false;

};
}
</script>
</head>
<body>
<div>
<div id="txtcontent" style="width:500px;height:250px;border: solid 1px gray">

</div>
<div>所有用户:<select id="listusers"></select> </div>
<div>你的昵称:<input type="text" id="username"/> </div>
<div>
消息内容:
<textarea style="width:500px;height:100px" id="txtmsg">

</textarea>
</div>
<div>
<button onclick="connectServer()">连接服务器</button>
<button onclick="send()">发送消息</button>
</div>
</div>

</body>
</html>

服务器端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php

//本机ip 121.42.176.99
//等下 要监听 9091端口

require_once __DIR__ . '/Workerman/Autoloader.php';
use Workerman\Worker;
use Workerman\Connection\AsyncTcpConnection;

// 创建一个Worker监听2345端口,使用http协议通讯
$tcp_worker = new Worker("websocket://121.42.176.99:9091");

// 启动1个进程对外提供服务
$tcp_worker->count = 1;
$clients=[];//保存客户端信息

$tcp_worker->onMessage = function($connection, $data)
{
global $clients;
if(preg_match("/^login:(\w{3,20})/i",$data,$result))//代表是客户端认证
{
if(!array_key_exists($connection->getRemoteIp(),$clients)) //必须是之前没有记录过
{
// $clients[$connection->getRemoteIp()]=$result[1];//保存所有客户端 格式为 ip=>昵称
$clients[$connection->getRemoteIp()]=["ip"=>$connection->getRemoteIp(),"name"=>$result[1],"conn"=>$connection];

$connection->send("notice:success");//代表给客户端一个连接提示
$connection->send("msg:welcome back ".$result[1]);//代表是发送普通文字消息
echo $connection->getRemoteIp().":".$result[1]." login".PHP_EOL;


//$connection->send("users:".json_encode($clients));
$users="users:".json_encode(array_column($clients,"name","ip"));
foreach($clients as $ip=>$set)
{
$set["conn"]->send($users);
}

}

}
else if(preg_match("/^msg:(.*?)/isU",$data,$msgset)) //代表 是客户端发送普通消息
{
if(array_key_exists($connection->getRemoteIp(),$clients)) //必须已经认证过得客户端
{
echo "get msg :".$msgset[1];
}
}
$connection->onClose=function ($connection)//客户端主动关闭
{
global $clients;
unset($clients[$connection->getRemoteIp()]);
};
};
$tcp_worker->onClose=function ($connection) use($clients)
{

};


// 运行worker
Worker::runAll();