本站测试实例访问地址: http://code.liuxinxiu.com/php/Interface/html/WebSocket.html
XML/HTML代码
- <!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="http://code.liuxinxiu.com/lib/bootstrap/3.3.2/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;
 - z-index:1000;
 - 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://code.liuxinxiu.com/lib/jquery/1.9.1/jquery.min.js"></script>
 - <script src="http://code.liuxinxiu.com/lib/bootstrap/3.3.2/bootstrap.min.js"></script>
 - <script>
 - $(function(){
 - var wsurl='ws://code.liuxinxiu.com:9090/php/webSocket/server.php';
 - var websocket;
 - var i = 0;
 - /******** 判断是否有webSocket对象 *******/
 - if(window.WebSocket){
 - websocket=new WebSocket(wsurl);
 - /******** 连接建立||发起webSocket连接 ********/
 - websocket.onopen = function(evevt){
 - console.log("Connected to WebSocket server.");
 - /******** 监听ready状态码 ********/
 - console.log('websocket.readyState:'+websocket.readyState);
 - /*********************************************************
 - 值为0值表示该连接尚未建立
 - 值为1表示连接建立和沟通是可能的
 - 值为2表示连接是通过将结束握手
 - 值为3表示连接已关闭或无法打开
 - *********************************************************/
 - /******** 判断状态码为1则连接成功即可正常通信********/
 - if(websocket.readyState==1){
 - $('.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消息数据
 - console.log("\n--->>message:\n"+event.data);
 - 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>
 
后端PHP代码部分:
PHP代码
- 2.php code:
 - <?php
 - $host = '127.0.0.1';
 - $port = '9090';
 - $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);
 - }
 - }
 - }
 - // 关闭监听的socket
 - socket_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("/\r\n/", $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 Handshake\r\n" .
 - "Upgrade: websocket\r\n" .
 - "Connection: Upgrade\r\n" .
 - "WebSocket-Origin: $host\r\n" .
 - "WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".
 - "Sec-WebSocket-Accept:$secAccept\r\n\r\n";
 - socket_write($client_conn,$upgrade,strlen($upgrade));
 - }
 
关于Javascript
React - comp
 

 2016/09/27 21:14 | by 
  
 
 
 
 
 


