爱程序网

我做的一个websocket的demo(php server)

来源: 阅读:

notice:

通过命令行执行php文件  如 php -q c:pathserver.php

通过本地web服务器访问 http://127.0.0.1/websocket/index.php即可

notice:
需要php5.3或以上的执行环境,和一个web服务器如apache
浏览器需支持html5 web socket
这里监听 socket端口 9505,如遇到端口被占用可能需要在这两个文件内修改端口或者杀死相应端口进程

页面手机上看起来比pc上好看!

1.客户端代码 html文件

1.client code:<!DOCTYPE html><html>    <head>        <title>chatdemo</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">简易聊天demo</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>        $(function(){            var wsurl = 'ws://127.0.0.1:9505/websocket/server.php';            var websocket;            var i = 0;            if(window.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) {                    var msg = JSON.parse(event.data); //解析收到的json消息数据                    var type = msg.type; // 消息类型                    var umsg = msg.message; //消息文本                    var uname = msg.name; //发送人                    i++;                    if(type == 'usermsg'){                        $('.show-area').append('<p class="bg-success message"><i class="glyphicon glyphicon-user"></i><a name="'+i+'"></a><span class="label label-primary">'+uname+' say: </span>'+umsg+'</p>');                    }                    if(type == 'system'){                        $('.show-area').append('<p class="bg-warning message"><a name="'+i+'"></a><i class="glyphicon glyphicon-info-sign"></i>'+umsg+'</p>');                    }                                        $('#message').val('');                     window.location.hash = '#'+i;                }                //发生错误                websocket.onerror = function(event){                    i++;                    console.log("Connected to WebSocket server error");                    $('.show-area').append('<p class="bg-danger message"><a name="'+i+'"></a><i class="glyphicon glyphicon-info-sign"></i>Connect to WebSocket server error.</p>');                    window.location.hash = '#'+i;                }                //连接关闭                websocket.onclose = function(event){                    i++;                    console.log('websocket Connection Closed. ');                    $('.show-area').append('<p class="bg-warning message"><a name="'+i+'"></a><i class="glyphicon glyphicon-info-sign"></i>websocket Connection Closed.</p>');                    window.location.hash = '#'+i;                }                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);                    }                  }                //按下enter键发送消息                $(window).keydown(function(event){                    if(event.keyCode == 13){                        console.log('user enter');                        send();                    }                });                //点发送按钮发送消息                $('.send').bind('click',function(){                    send();                });                            }            else{                alert('该浏览器不支持web socket');            }        });            </script>            </body></html>
View Code

 

2.socket服务器端代码 php文件

2.php code:<?php$host = '127.0.0.1'; $port = '9505'; $null = NULL; //创建tcp socket$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);socket_bind($socket, 0, $port);//监听端口socket_listen($socket);//连接的client socket 列表$clients = array($socket);//设置一个死循环,用来监听连接 ,状态while (true) {        $changed = $clients;    socket_select($changed, $null, $null, 0, 10);        //如果有新的连接    if (in_array($socket, $changed)) {        //接受并加入新的socket连接        $socket_new = socket_accept($socket);         $clients[] = $socket_new;                //通过socket获取数据执行handshake        $header = socket_read($socket_new, 1024);         perform_handshaking($header, $socket_new, $host, $port);                //获取client ip 编码json数据,并发送通知        socket_getpeername($socket_new, $ip);        $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected')));        send_message($response);        $found_socket = array_search($socket, $changed);        unset($changed[$found_socket]);    }        //轮询 每个client socket 连接    foreach ($changed as $changed_socket) {                    //如果有client数据发送过来        while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)        {            //解码发送过来的数据            $received_text = unmask($buf);             $tst_msg = json_decode($received_text);              $user_name = $tst_msg->name;             $user_message = $tst_msg->message;                         //把消息发送回所有连接的 client 上去            $response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message)));            send_message($response_text);            break 2;         }                //检查offline的client        $buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);        if ($buf === false) {             $found_socket = array_search($changed_socket, $clients);            socket_getpeername($changed_socket, $ip);            unset($clients[$found_socket]);            $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected')));            send_message($response);        }    }}// 关闭监听的socketsocket_close($sock);//发送消息的方法function send_message($msg){    global $clients;    foreach($clients as $changed_socket)    {        @socket_write($changed_socket,$msg,strlen($msg));    }    return true;}//解码数据function unmask($text) {    $length = ord($text[1]) & 127;    if($length == 126) {        $masks = substr($text, 4, 4);        $data = substr($text, 8);    }    elseif($length == 127) {        $masks = substr($text, 10, 4);        $data = substr($text, 14);    }    else {        $masks = substr($text, 2, 4);        $data = substr($text, 6);    }    $text = "";    for ($i = 0; $i < strlen($data); ++$i) {        $text .= $data[$i] ^ $masks[$i%4];    }    return $text;}//编码数据function mask($text){    $b1 = 0x80 | (0x1 & 0x0f);    $length = strlen($text);        if($length <= 125)        $header = pack('CC', $b1, $length);    elseif($length > 125 && $length < 65536)        $header = pack('CCn', $b1, 126, $length);    elseif($length >= 65536)        $header = pack('CCNN', $b1, 127, $length);    return $header.$text;}//握手的逻辑function perform_handshaking($receved_header,$client_conn, $host, $port){    $headers = array();    $lines = preg_split("/rn/", $receved_header);    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: $hostrn" .    "WebSocket-Location: ws://$host:$port/demo/shout.phprn".    "Sec-WebSocket-Accept:$secAcceptrnrn";    socket_write($client_conn,$upgrade,strlen($upgrade));}
View Code

 

以后有空再整份java版本的

相关文章列表:
关于爱程序网 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助