WebSocket中的长连接以及超时问题的解决问题(代码)

WebSocket中的长连接以及超时问题的解决问题(代码)

内容导读

收集整理的这篇技术教程文章主要介绍了WebSocket中的长连接以及超时问题的解决问题(代码),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含8011字,纯文字阅读大概需要12分钟

内容图文

本篇文章给大家带来的内容是关于WebSocket中的长连接以及超时问题的解决问题(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
<?phpset_time_limit(0);class SocketService{

private $address
= 'localhost';

private $port = 80;

private $_sockets;

public function __construct($address = '', $port='')

{



if(!empty($address)){





$this->address = $address;



}



if(!empty($port)) {





$this->port = $port;



}

}

public function service(){



//获取tcp协议号码。



$tcp = getprotobyname("SOL_TCP");




 # 获取与协议名称关联的协议号



$sock = socket_create(AF_INET, SOCK_STREAM, $tcp);
# 创建一个套接字(通讯节点)



socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
# 设置套接字选项



if($sock < 0)



{





throw new Exception("failed to create socket: ".socket_strerror($sock)."n");



}



socket_bind($sock, $this->address, $this->port);

# 绑定



socket_listen($sock, $this->port);


# 监听套接字上的连接



$this->_sockets = $sock;


 }

public function run(){



$this->service();



$clients[] = $this->_sockets;
 # 数组存储 每个socket



# 让服务器无限获取客户端传过来的信息



while (true){





$changes = $clients;





$write = NULL;





$except = NULL;





socket_select($changes,
$write,
$except, NULL);





foreach ($changes as $key => $_sock){







if($this->_sockets == $_sock){
# 判断是不是新接入的socket









if(($newClient = socket_accept($_sock))
=== false){

# 接受新的套接字上的连接
 socket_accept的作用就是接受socket_bind()所绑定的主机发过来的套接流











die('failed to accept socket: '.socket_strerror($_sock)."n");
# 返回描述套接字错误的字符串









}









$line = trim(socket_read($newClient, 1024));
# 读取客户端传过来的资源,并转化为字符串

 socket_read的作用就是读出socket_accept()的资源并把它转化为字符串









$this->handshaking($newClient, $line);









//获取client ip









socket_getpeername ($newClient, $ip);
















 # 查询给定套接字的远程端,这可能导致主机/端口或UNIX文件系统路径,具体取决于其类型。









$clients[$ip] = $newClient;







} else {









# 读取该socket的信息,注意:第二个参数是引用传参即接收数据,第三个参数是接收数据的长度









$lenght = socket_recv($_sock, $buffer,
2048, 0);






 # 从已连接的socket接收数据
 $lenght 接收到字符串长度









$msg = $this->message($buffer);




# 接收到的信息









//在这里业务代码









fwrite(STDOUT, 'Please input a argument:');









$response = trim(fgets(STDIN));//









$this->send($_sock, $response);


























 # 第二个参数是获取数据

要发送的信息









$this->send($_sock, '在线');







}





}



}

}

/**

 * 握手处理

 * @param $newClient socket

 * @return int
接收到的信息

 */

public function handshaking($newClient, $line){



$headers = array();



$lines = preg_split("/rn/", $line);
 # 通过一个正则表达式分隔字符串。



foreach($lines as $line)



{





$line = chop($line);

# 移除字符串右端的空白字符或其他预定义字符





if(preg_match('/A(S+): (.*)z/', $line, $matches))





{







$headers[$matches[1]] = $matches[2];





}



}



$secKey = $headers['Sec-WebSocket-Key'];



$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));



$upgrade
= "HTTP/1.1 101 Web Socket Protocol Handshakern" .





"Upgrade: websocketrn" .





"Connection: Upgradern" .





"WebSocket-Origin: $this->addressrn" .





"WebSocket-Location: ws://$this->address:$this->port/服务器地址rn".





"Sec-WebSocket-Accept:$secAcceptrnrn";



return socket_write($newClient, $upgrade, strlen($upgrade));

# socket_write的作用是向socket_create的套接流写入信息,或者向socket_accept的套接流写入信息

}

/**

 * 解析接收数据

 * @param $buffer

 * @return null|string

 */

public function message($buffer){



$len = $masks = $data = $decoded = null;



$len = ord($buffer[1]) & 127;



if ($len === 126)
{





$masks = substr($buffer, 4, 4);





$data = substr($buffer, 8);



} else if ($len === 127)
{





$masks = substr($buffer, 10, 4);





$data = substr($buffer, 14);



} else
{





$masks = substr($buffer, 2, 4);





$data = substr($buffer, 6);



}



for ($index = 0; $index < strlen($data); $index++) {





$decoded .= $data[$index] ^ $masks[$index % 4];



}



return $decoded;

}

/**

 * 发送数据

 * @param $newClinet 新接入的socket

 * @param $msg
 要发送的数据

 * @return int|string

 */

public function send($newClinet, $msg){



$msg = $this->frame($msg);



socket_write($newClinet, $msg, strlen($msg));
 # 写入套接字

}

public function frame($s) {



$a = str_split($s, 125);

# 把字符串分割到数组中 第二个长度参数



if (count($a) == 1) {





return "x81" . chr(strlen($a[0])) . $a[0];



}



$ns = "";



foreach ($a as $o) {





$ns .= "x81" . chr(strlen($o)) . $o;



}



return $ns;

}

/**

 * 关闭socket

 */

public function close(){



# socket_close的作用是关闭socket_create()或者socket_accept()所建立的套接流



return socket_close($this->_sockets);

}}$sock = new SocketService();$sock->run();


网上看到很多说会断开链接,设置心跳包也没有用

我这里直接配置了下 set_time_limit(0);   改变 php.ini中的 max_execution_time设置时间 然后就没有断线的问题了! 也保证了持久连接!

HTML部分


<!DOCTYPE html><html><head>

<title>Socket 测试</title>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, user-scalable=no">

<link href="https://cdn.bootcss.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"> <style type="text/css">



html, body {





min-height: 100%; }



body {





margin: 0;





padding: 0;





width: 100%;





font-family: "Microsoft Yahei",sans-serif, Arial; }



.container {





text-align: center; }



.title {





font-size: 16px;





color: rgba(0, 0, 0, 0.3);





position: fixed;





line-height: 30px;





height: 30px;





left: 0px;





right: 0px;





background-color: white; }



.content {





background-color: #f1f1f1;





border-top-left-radius: 6px;





border-top-right-radius: 6px;





margin-top: 30px; }



.content .show-area {





text-align: left;





padding-top: 8px;





padding-bottom: 168px; }



.content .show-area .message {





width: 70%;





padding: 5px;





word-wrap: break-word;





word-break: normal; }



.content .write-area {





position: fixed;





bottom: 0px;





right: 0px;





left: 0px;





background-color: #f1f1f1;





z-index: 10;





width: 100%;





height: 160px;





border-top: 1px solid #d8d8d8; }



.content .write-area .send {





position: relative;





top: -28px;





height: 28px;





border-top-left-radius: 55px;





border-top-right-radius: 55px; }



.content .write-area #name{





position: relative;





top: -20px;





line-height: 28px;





font-size: 13px; }

</style></head><body><div class="container">

<div class="title">Socket 测试长连接</div>

<div class="content">



<div class="show-area"></div>



<div class="write-area">





<div><button class="btn btn-default send" >发送</button></div>





<div><input name="name" id="name" type="text" placeholder="input your name"></div>





<div>







<textarea name="message" id="message" cols="38" rows="4" placeholder="input your message..."></textarea>





</div>



</div>

</div></div><script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script><script src="https://cdn.bootcss.com/bootstrap/3.3.2/js/bootstrap.min.js"></script><script>



var wsurl = 'ws://localhost:80/websocket/test2.php';



var websocket;



websocket = new WebSocket(wsurl);





//连接建立





websocket.onopen = function(evevt){







console.log("Connected to WebSocket server.");







$('.show-area').append('<p class="bg-info message"><i class="glyphicon glyphicon-info-sign"></i>Connected to WebSocket server!</p>');





}





//收到消息





websocket.onmessage = function(event) {







console.log(event);







$('.show-area').append('<p class="bg-info message"><i class="glyphicon glyphicon-info-sign"></i>'+event.data+'</p>');





}





//发生错误





websocket.onerror = function(event){







console.log("Connected to WebSocket server error");







$('.show-area').append('<p class="bg-danger message"><a name=""></a><i class="glyphicon glyphicon-info-sign"></i>Connect to WebSocket server error.</p>');





}





//连接关闭





websocket.onclose = function(event){







console.log('websocket Connection Closed. ');







$('.show-area').append('<p class="bg-warning message"><a name=""></a><i class="glyphicon glyphicon-info-sign"></i>websocket Connection Closed.</p>');





}

// 发送信息





function send(){







var name = $('#name').val();







var message = $('#message').val();







if(!name){









alert('请输入用户名!');









return false;







}







if(!message){









alert('发送消息不能为空!');









return false;







}







 var msg = {









 message: message,









 name: name







 };







try{









 websocket.send(JSON.stringify(msg));







} catch(ex) {









console.log(ex);







}





}





//点发送按钮发送消息





$('.send').bind('click',function(){







send();





});</script></body></html>

以上就是WebSocket中的长连接以及超时问题的解决问题(代码)的详细内容,更多请关注Gxl网其它相关文章!

内容总结

以上是为您收集整理的WebSocket中的长连接以及超时问题的解决问题(代码)全部内容,希望文章能够帮你解决WebSocket中的长连接以及超时问题的解决问题(代码)所遇到的程序开发问题。 如果觉得技术教程内容还不错,欢迎将网站推荐给程序员好友。

内容备注

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。


本文关键词:

联系我们

在线咨询:点击这里给我发消息

邮件:w420220301@qq.com