首頁 > php教程 > php手册 > PHP实现Socket侦听消息简单示例

PHP实现Socket侦听消息简单示例

WBOY
發布: 2016-06-06 19:57:45
原創
1380 人瀏覽過

流程: 服务器端不断侦听socket请求 客户端向服务器发送一个含有独特key的socket请求 服务器接收到该请求,获得客户端的socket,进行一次“握手”,即向客户端发送含有客户端key的特定消息 客户端接收到服务器发送的消息,表明连接成功,可以向服务器发消息

流程:

服务器端不断侦听socket请求

客户端向服务器发送一个含有独特key的socket请求

服务器接收到该请求,获得客户端的socket,进行一次“握手”,即向客户端发送含有客户端key的特定消息

客户端接收到服务器发送的消息,表明连接成功,可以向服务器发消息

服务器握手成功后,开始侦听该客户端发送的消息,并且对消息进行解码

前端使用html5的 WebSocket API


浏览器打开index.php

后台执行php server.php(首先要配置php命令可用)


index.php:






<script>
	
	so = new WebSocket(&#39;ws://localhost:8080&#39;);
	
	so.onopen = function()
		{
			if (so.readyState==1)
			{	alert(&#39;socket connected&#39;);
				so.send(&#39;hello world&#39;);
			}
			
		};
		
	so.onclose = function()
		{
			alert(&#39;socket closed&#39;);
		};
		
	

</script>

登入後複製

server.php

<?php $sk = new Sock("localhost", 8080);

$sk->run();

class Sock
{
	public $master;
	
	public function __construct($address, $port)
	{
		//create a socket
		$this->master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
		socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1);
		
		//bind socket with address and port
		socket_bind($this->master, $address, $port);
		
		//listen!
		socket_listen($this->master);
		
		echo ('Server Started : '.date('Y-m-d H:i:s') ."\n");
		echo ('Listening on   : '.$address.' port '.$port ."\n");
	}
	
	function run()
	{
		while (true)
		{
			if ($client = socket_accept($this->master))
			//if a socket is accepted
			{
				$len = 0;
				$buffer = '';
				
				do{
					$l = socket_recv($client, $buf, 1000, 0);
					$len += $l;
					$buffer .= $buf;
				}
				while($l == 1000);
				
				//handshake
				$buf  = substr($buffer,strpos($buffer,'Sec-WebSocket-Key:')+18);
				
				$key  = trim(substr($buf,0,strpos($buf,"\r\n")));

				$new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));

				$new_message = "HTTP/1.1 101 Switching Protocols\r\n";
				$new_message .= "Upgrade: websocket\r\n";
				$new_message .= "Sec-WebSocket-Version: 13\r\n";
				$new_message .= "Connection: Upgrade\r\n";
				$new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";

				socket_write($client, $new_message, strlen($new_message));
				//handshake over
				
				while(true)
				//now listen the message sent by client
				//because we know client is about to sent a message refer to index.php
				{
					$buf = '';
					$len = 0;
					$buffer = '';
					
					do{
						$l = socket_recv($client, $buf, 1000, 0);
						$len += $l;
						$buffer .= $buf;
					}while($l == 1000);
					
					echo $this->decode($buffer)."\n";
					
					break;
				}
				
			}
		}
	}
	
	function decode($str){
		$mask = array();
		$data = '';
		$msg = unpack('H*', $str);
		$head = substr($msg[1], 0, 2);

		if ($head == '81') 
		{
			$len = substr($msg[1], 2, 2);
			$len = hexdec($len);

			if(substr($msg[1], 2, 2) == 'fe')
			{
				$len = substr($msg[1], 4, 4);
				$len = hexdec($len);
				$msg[1] = substr($msg[1],4);
			}
			else if(substr($msg[1], 2, 2) == 'ff'){
				$len = substr($msg[1], 4, 16);
				$len = hexdec($len);
				$msg[1] = substr($msg[1], 16);
			}

			$mask[] = hexdec(substr($msg[1], 4, 2));
			$mask[] = hexdec(substr($msg[1], 6, 2));
			$mask[] = hexdec(substr($msg[1], 8, 2));
			$mask[] = hexdec(substr($msg[1], 10, 2));
			$s = 12;
			$n = 0;
		}
		else
		{
			return 'decode failed';
		}

		$e = strlen($msg[1]) - 2;
		
		for ($i = $s; $i 
登入後複製


來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板