websocket+php+socket聊天室
来源:互联网 发布:python 支付宝 api 编辑:程序博客网 时间:2024/06/05 00:54
客户端(聊天前端页面):
<!DOCTYPE html><html><head> <title>mychat_socket</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>
服务端(php+socket):
<?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("/\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));}
阅读全文
0 0
- websocket+php+socket聊天室
- php基于websocket搭建简易聊天室(socket)
- php websocket聊天室
- 利用Swoole实现PHP+websocket 聊天室
- 利用Swoole实现PHP+websocket 聊天室
- 利用Swoole实现PHP+websocket 聊天室
- php基于websocket实现的在线聊天室
- 利用Swoole实现PHP+websocket 聊天室
- 利用Swoole实现PHP+websocket 聊天室
- WebSocket 聊天室
- WebSocket聊天室
- websocket聊天室
- websocket聊天室
- websocket聊天室
- Websocket和PHP Socket编程
- 使用Node.js+Socket.IO搭建WebSocket实时应用(聊天室)
- Node.js+Socket.IO实现的WebSocket群聊天室源码
- Node.js websocket 使用 socket.io库实现实时聊天室
- CentOS-7制作本地源的具体方法
- HTTP协议(2)HTTP协议中的请求信息
- cannot find cdtool at
- PyQt学习(3)
- 独家解读:简单又强大的配置文件 Config 读写类
- websocket+php+socket聊天室
- 透视投影详解
- 加载第三方apk获取资源Resources$NotFoundException: Resource ID #0x0
- editor上传视频无法播放的问题
- Spring MVC入门(二)
- Spring——注解详解
- 双方同时开启TCP连接
- spring+Hibernate
- 根Activity组件启动过程