首页 > 作文

老雷socket编程之websocket实现

更新时间:2023-04-07 06:50:17 阅读: 评论:0

老雷socket编程之websocket实现

我们主要实现私聊和群聊两个功能,要在web端实现想微信qq那样的即时通讯的功能,我们需要了解一下websocket。
websocket是一种可以双向通讯的长连接协议,http是获取完数据就关闭,websocket则可以一直连接,就像铺了一条管道一样,水可以一直流着。

一、websocket前端

    var ws = new websocket("ws://127.0.0.1.com:8282");    ws.onopen=function(){        var msg = json.stringify({            type: "login",            content: "login"        });        ws.nd(msg);    }        ws.onmessage = function (e){         console.log(e);        //服务器发送的内容        var res = json.par(e.data);        switch(res.type){            ca "login":                                break;            ca "pm":                                break;            ca "grouppm":                                break;                        }    }    ws.onerror=function (e){         console.log(e);    }    ws.onclo=function (e){         console.log(e);    }

二、服务端

客户端发送http请求,带上c-websocket-key,
服务端握手 加密key,发送给客户端。
双方能进行交流。

发送接收消息需要进英语主谓宾行打包encode 解包decode。

<?phpclass socketrvice{    public $host="tcp://0.0.0.0:8000";    private $address;    private $port;    private $_sockets;    public $clients;    public $maxid=1000;    public function __construct($address = '', $port='')    {            if(!empty($address)){                $this->address = $address;            }            if(!empty($port)) {                $this->port = $port;            }    }        public function onconnect($client_id){        echo  "client client_id:{$client_id}   \n";             }        public function onmessage($client_id,$msg){        //发给所有的        foreach($this->clients as $kk=>$cc){            if($kk>0){                $this->nd($cc, $msg);            }                                        }        }        public function onclo($client_id){        echo "$client_id clo \n";    }        public function rvice(){        //获取tcp协议号码。        $tcp = getprotobyname("tcp");        $sock = stream_socket_rver($this->host, $errno, $errstr);;                if(!$sock)    老年妇女    {            throw new exception("failed to create socket: ".socket_strerror($sock)."\n");        }        stream_t_blocking($sock,0);        $this->_sockets = $sock;         echo "listen on $this->address $this->host ... \n";    }     public function run(){        $this->rvice();        $this->clients[] = $this->_sockets;        while (true){            $changes = $this->clients;            //$write = null;            //$except = null;            stream_lect($changes,  $write,  $except, null);            foreach ($changes as $key => $_sock){                if($this->_sockets == $_sock){ //判断是不是新接入的socket                    if(($newclient = stream_socket_accept($_sock))  === fal){                        unt($this->clients[$key]);                        continue;                    }                    $line = trim(stream_socket_recvfrom($newclient, 1024));                    //握手                    $this->handshaki宜昌的大学ng($newclient, $line);                    $this->maxid++;                    $this->clients[$this->maxid] = $newclient;                    $this->onconnect($this->maxid);                } el {                    $res=@stream_socket_recvfrom($_sock,  2048);                    //客户端主动关闭                    if(strlen($res) < 9) {                        stream_socket_shutdown($this->clients[$key],stream_shut_rdwr);                        unt($this->clients[$key]);                        $this->onclo($key);                    }el{                        //解密                        $msg = $this->decode($res);                        $this->onmessage($key,$msg);                    }                                                         }            }        }    }     /**     * 握手处理     * @param $newclient socket     * @return int  接收到的信息     */    public function handshaking($newclient, $line){         $headers = array();        $lines = preg_split("/\r\n/", $line);        foreach($lines as $line)        {            $line = chop($line);            if(preg_match('/\a(\s+): (.*)\z/', $line, $matches))            {                $headers[$matches[1]] = $matches[2];            }        }        $ckey = $headers['c-websocket-key'];        $caccept = ba64_encode(pack('h*', sha1($ckey . '258eafa5-e914-47da-95ca-c5ab0dc85b11')));        $upgrade  = "http/1.1 101 web socket protocol handshake\r\n" .            "upgrade: websocket\r\n" .            "connection: upgrade\r\n" .            "websocket-origin: $this->address\r\n" .            "websocket-location: ws://$this->address:$this->port/websocket/websocket\r\n".            "c-websocket-accept:$caccept\r\n\r\n";        return stream_socket_ndto($newclient, $upgrade);    }                    /**     * 发送数据     * @param $newclinet 新接入的socket     * @param $msg   要发送的数据     * @return int|string     */    public function nd($newclinet, $msg){        $msg = $this->encode($msg);        stream_socket_ndto($newclinet, $msg);    }    /**     * 解析接收数据     * @param $buffer     * @return null|string     */    public function decode($buffer){        $len = $masks = $data = $decoded = null;        $len = ord($buffer[1]) & 127;        if ($len === 126)  {            $masks = substr($buffer, 4, 4);            $data = substr($buffer, 8);        } el if ($len === 127)  {            $masks = substr($buffer, 10, 4);            $data = substr($buffer, 14);        } el  描写乡愁的诗句{            $masks = substr(评职称个人总结$buffer, 2, 4);            $data = substr($buffer, 6);        }        for ($index = 0; $index < strlen($data); $index++) {            $decoded .= $data[$index] ^ $masks[$index % 4];        }        return $decoded;    }         /**    *打包消息    **/     public function encode($buffer) {        $first_byte="\x81";        $len=strlen($buffer);        if ($len <= 125) {            $encode_buffer = $first_byte . chr($len) . $buffer;        } el {            if ($len <= 65535) {                $encode_buffer = $first_byte . chr(126) . pack("n", $len) . $buffer;            } el {                $encode_buffer = $first_byte . chr(127) . pack("xxxxn", $len) . $buffer;            }        }        return $encode_buffer;    }     /**     * 关闭socket     */    public function clo(){        return socket_clo($this->_sockets);    }} $sock = new socketrvice('127.0.0.1','9000');$sock->run();

三、常见应用

1.聊天室、群聊 实现类似的web版本

2.im私聊、客服 实现类似qq聊天,和即时客服交流

3.消息推送 建立即时的web消息推送

课后练习
实现聊天室 跟 个人聊天
前端格式

var msg = json.stringify({type: "login",content: "login"});var msg = json.stringify({type: "group",content: "login",gid:123});var msg = json.stringify({type: "pm",content: "login",uid:123});

本文发布于:2023-04-07 06:50:15,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/dda78e3d1967020517279e8d70adcf6a.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:老雷socket编程之websocket实现.doc

本文 PDF 下载地址:老雷socket编程之websocket实现.pdf

标签:消息   数据   客服   客户端
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图