示例:PHP使用socket协议实现的即时通信功能
一、在服务器根目录建立SocketServer.php文件,打开文件,复制下面内容,保存。
![](https://img-blog.csdn.net/20171130100358321?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcnlvdHkxMjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20171130100442246?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcnlvdHkxMjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20171130100554450?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcnlvdHkxMjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20171130100641179?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcnlvdHkxMjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
<?php
/*socket服务器程序 start*/
//创建一个套接字
$sock=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
//如果绑定套接字失败则退出程序
if(!socket_bind($sock, gethostbyname($_SERVER["HTTP_HOST"]),2233)) exit;
//监听
socket_listen($sock,5);
//设置超时时间
set_time_limit(0);
//客户端套接字
$clients_socket=array();
//客户端监听套接字
$clients_listen = array();
//设置套接字为非阻塞模式
socket_set_nonblock($sock);
while(true){
//服务器监听套接字
$servers_listen = array($sock);
if(count($clients_socket)>0) $clients_listen=$clients_socket;
//合并套接字
$all_socket=array_merge($servers_listen,$clients_listen);
//监视套接字是否有消息传来
$all_msg=socket_select($all_socket,$write,$except,NULL);
//查询连接套接字消息数量
$server_msg=socket_select($servers_listen,$write,$except,0);
//如果服务器有未处理的消息
if($server_msg>0){
//循环接受套接字的连接请求
for($i=0;$i<$server_msg;$i++){
//接受连接,并且保存套接字到数组中
$clients_socket[] =$accept_socekt= socket_accept($sock);
}
continue;
}
//查询客户端未读消息的数量
$clients_msg=socket_select($clients_listen,$write,$except,0);
if($clients_msg>0){
foreach ($clients_listen as $key => $value) {
$message = socket_read($value, 1024);
//如果客户端断开连接
if($message===""){
//查询套接字的位置
$position = array_search($value, $clients_socket);
//删除套接字
unset($clients_socket[$position]);
continue;
}
//如果客户端发来消息
if(strlen($message)>0){
//把消息转换成数组
$receive_data=json_decode($message,true);
//消息处理 start
$file=fopen("test.txt","a+");
switch($receive_data["state"]){
//登记消息
case "0":{
//如果被登记的套接字在线
if($clients_socket["user".$receive_data["userId"]]) break;
//查询被登记套接字的位置
$position = array_search($value, $clients_socket);
//登记套接字
$clients_socket["user".$receive_data["userId"]]=$clients_socket[$position];
//删除未登记的套接字
unset($clients_socket[$position]);
break;
}
//客户端发送私聊消息
case "1":{
//判断接收者是否在线
if($clients_socket["user".$receive_data["targetId"]]){
//消息类型标志为私聊消息
$send_data["flages"]="2";
//消息内容
$send_data["message"]=$receive_data["message"];
//发送消息者的ID
$send_data["userId"]=substr($key,4);
//发送消息者的名称
$send_data["userName"]="name";
$data=json_encode($send_data);
//向接收者发送消息
socket_write($clients_socket["user".$receive_data["targetId"]], $data, strlen($data));
}else{
//通知发送者用户不在线
$send_data["flages"]="3";
$data=json_encode($send_data);
socket_write($value,$data,strlen($data));
}
break;
}
//客户端发送世界消息
case "2":{
//消息类型标志为世界消息
$send_data["flages"]="1";
//消息内容
$send_data["message"]=$receive_data["message"];
//发送消息者的ID
$send_data["userId"]=substr($key,4);
//发送消息者的名称
$send_data["userName"]="name";
//向所有在线用户发送消息
$data=json_encode($send_data);
foreach ($clients_socket as $key1 => $value1) {
socket_write($value1,$data, strlen($data));
}
break;
}
//终止服务器
case "exit":{
set_time_limit(1);
exit;
break;
}
}
fclose($file);
//消息处理 end
}
}
}
}
/*socket服务器程序 end*/
二、在浏览器输入localhost/SocketServer.php回车,正常开启Socket服务器后即可关闭浏览器
四、登记套接字ID
1.客户端一的数据0输入{"state":"0","userId":"1"}点击发送
2.客户端二的数据0输入{"state":"0","userId":"2"}点击发送
3.客户端二的数据0输入{"state":"0","userId":"3"}点击发送
1.客户端一的数据0输入{"state":"0","userId":"1"}点击发送
2.客户端二的数据0输入{"state":"0","userId":"2"}点击发送
3.客户端二的数据0输入{"state":"0","userId":"3"}点击发送
五、发送消息
1.客户端一给客户端2发送消息,在客户端一的数据1输入{"state":"1","targetId":"2","message":"user_1 send to user_2"}点击发送
1.客户端一给客户端2发送消息,在客户端一的数据1输入{"state":"1","targetId":"2","message":"user_1 send to user_2"}点击发送
2.客户端一给所有用户广播消息 ,在客户端一的数据2输入{"state":"2","message":"user_1 send to all"}
3.客户端一的数据0输入{"state":"exit"}退出套接字服务器程序。
转载自:https://user.qzone.qq.com/474410068/blog/1474988358