HTML5 WebSocket
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。......
OK!这是官方解释。》》
这不重要,今天工作之余给大家推荐一个好用的WebSocket集成模块 GoEasy !
因为官方的演示代码已经非常详细了。在这里我就不多赘述了。
直接贴贴记录一下代码
后台代码(PHP),实现 消息推送/接收
private function curlPost($url, $post_data = array(), $timeout = 5, $header = "", $data_type = "") { $header = empty($header) ? '' : $header; //⽀持json数据数据提交 if($data_type == 'json'){ $post_string = json_encode($post_data); }elseif($data_type == 'array') { $post_string = $post_data; }elseif(is_array($post_data)){ $post_string = http_build_query($post_data, '', '&'); } $ch = curl_init(); // 启动⼀个CURL会话 curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求不验证证书和hosts curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在 curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟⽤户使⽤的浏览器 //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使⽤⾃动跳转 //curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // ⾃动设置Referer curl_setopt($ch, CURLOPT_POST, true); // 发送⼀个常规的Post请求 curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置超时限制防⽌死循环 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); //curl_setopt($curl, CURLOPT_HEADER, 0); // 显⽰返回的Header区域内容 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以⽂件流的形式返回 curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头 $result = curl_exec($ch); // 打印请求的header信息 //$a = curl_getinfo($ch); //var_dump($a); curl_close($ch); return$result; } private function websocket($res){ // file_put_contents('./git_error_logs.json',json_encode($res).PHP_EOL,FILE_APPEND); $url = 'http://rest-hangzhou.goeasy.io/publish'; // $content=$this->unicode_decode($res); $content=$res; file_put_contents('./git_error_logs.json',date("Y-m-d H:i:s",time()).'=> '.$content.PHP_EOL,FILE_APPEND); $post_data = array("appkey"=>"你的appkey","channel"=>'随便名命就是一个标识,接收要用',"content"=>$content); $header = array('Content-type:application/x-www-form-urlencoded'); $this->curlPost($url,$post_data,10,$header); } //将UNICODE编码后的内容进行解码 private function unicode_decode($name) { //转换编码,将Unicode编码转换成可以浏览的utf-8编码 $pattern = '/([\w]+)|(\\\u([\w]{4}))/i'; preg_match_all($pattern, $name, $matches); if (!empty($matches)) { $name = ''; for ($j = 0; $j < count($matches[0]); $j++) { $str = $matches[0][$j]; if (strpos($str, '\\u') === 0) { $code = base_convert(substr($str, 2, 2), 16, 10); $code2 = base_convert(substr($str, 4), 16, 10); $c = chr($code).chr($code2); $c = iconv('UCS-2', 'UTF-8', $c); $name .= $c; } else { $name .= $str; } } } return $name; }
极简demo
$get=$_GET['res']; $url = 'http://rest-hangzhou.goeasy.io/publish'; $content=$get.'AAA'; $post_data = array("appkey"=>"你的appkey","channel"=>'随便名命,但是接收要用到',"content"=>$content); echo php_ajax($url,$post_data); function php_ajax($url, $post_data) { $postdata = http_build_query($post_data); $options = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-type:application/x-www-form-urlencoded', 'content' => $postdata, 'timeout' => 15 * 60 ) ); $context = stream_context_create($options); $result = file_get_contents($url, false, $context); return $result; }
前台代码(js),实现 消息推送/接收
//初始化 var goeasy = GoEasy.getInstance({ host:"hangzhou.goeasy.io", //若是新加坡区域:singapore.goeasy.io appkey:"你的appkey", modules:['pubsub']//根据需要,传入‘pubsub’或'im’,或数组方式同时传入 }); oConnect.onclick=function(){ //建立连接 goeasy.connect({ id:"001", //pubsub选填,im必填,最大长度60字符 data:{"avatar":"/www/xxx.png","nickname":"AAAaaa",'channel':"后台发送方的名命"}, //必须是一个对象,pubsub选填,im必填,最大长度300字符,用于上下线提醒和查询在线用户列表时,扩展更多的属性 onSuccess: function () { //连接成功 console.log("GoEasy connect successfully.") //连接成功 }, onFailed: function (error) { //连接失败 console.log("Failed to connect GoEasy, code:"+error.code+ ",error:"+error.content); }, onProgress:function(attempts) { //连接或自动重连中 console.log("GoEasy is connecting", attempts); } }); // ws=new WebSocket('ws://localhost:5000'); // ws.onopen=function(){ // oUl.innerHTML+="<li>客户端已连接</li>"; // } // ws.onmessage=function(evt){ // oUl.innerHTML+="<li>"+evt.data+"</li>"; // } // ws.onclose=function(){ // oUl.innerHTML+="<li>客户端已断开连接</li>"; // }; // ws.onerror=function(evt){ // oUl.innerHTML+="<li>"+evt.data+"</li>"; // }; }; var pubsub = goeasy.pubsub; oSend.onclick=function(){ $.get('http://test.com/test2.php',{res:oInput.value}); // pubsub.publish({ // channel: "Do_not_move_it",//替换为您自己的channel // message: oInput.value,//替换为您想要发送的消息内容 // onSuccess:function(){ // oUl.innerHTML+="<li>消息发布成功!</li>"; // console.log("消息发布成功。"); // }, // onFailed: function (error) { // oUl.innerHTML+="<li>消息发送失败,错误编码:"+error.code+" 错误信息:"+error.content+"</li>"; // console.log("消息发送失败,错误编码:"+error.code+" 错误信息:"+error.content); // } // }); pubsub.subscribe({ channel: "Do_not_move_it",//替换为您自己的channel onMessage: function (message) { oUl.innerHTML+="<li>成功"+message.content+"</li>"; console.log("Channel:" + message.channel + " content:" + message.content); }, onSuccess: function (message) { console.log("Channel订阅成功。"); console.log(message); }, onFailed: function (error) { console.log("Channel订阅失败, 错误编码:" + error.code + " 错误信息:" + error.content) } }); } oquit.onclick=function(){ //断开连接 goeasy.disconnect({ onSuccess: function(){ console.log("GoEasy disconnect successfully.") }, onFailed: function(error){ console.log("Failed to disconnect GoEasy, code:"+error.code+ ",error:"+error.content); } }); }
具体情况记得根据自身情况改进哦!如有纰漏欢迎各路大神指正