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);
            }
        });
    }

具体情况记得根据自身情况改进哦!如有纰漏欢迎各路大神指正

posted @ 2022-07-13 18:36  芒果鱼  阅读(206)  评论(0编辑  收藏  举报