示例:PHP使用socket协议实现的即时通信功能

示例:PHP使用socket协议实现的即时通信功能
一、在服务器根目录建立SocketServer.php文件,打开文件,复制下面内容,保存。
<?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服务器后即可关闭浏览器

三、 下载socket测试工具( http://pan.baidu.com/s/1b59nWy ),解压后打开三个测试客户端,分别输入服务器地址127.0.0.1,端口号2233,点击TCP连接。

四、登记套接字ID
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"}点击发送

2.客户端一给所有用户广播消息 ,在客户端一的数据2输入{"state":"2","message":"user_1 send to all"}

3.客户端一的数据0输入{"state":"exit"}退出套接字服务器程序。


转载自:https://user.qzone.qq.com/474410068/blog/1474988358
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值