php使用Socket实现聊天室功能(书中的代码)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了php使用Socket实现聊天室功能(书中的代码),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3944字,纯文字阅读大概需要6分钟。
内容图文
这只是一种技术
<?php $host = "127.0.0.1"; // 指定监听的端口,注意该端口不能与现有应用的端口冲突 $port = '9505'; $null = null; // 创建Socket。AF_INET:代表通信时使用IPv4协议;SOCK_STREAM:代表传输的数据是二进制流数据;SOL_TCP:代表底层使用的协议是TCP $socket = socket_create ( AF_INET, SOCK_STREAM, SOL_TCP ); // 指定Socket相应的属性。SOL_SOCKET:设定协议的等级;SO_REUSEADDR:设置端口释放之后可以立即被使用 socket_set_option ( $socket, SOL_SOCKET, SO_REUSEADDR, 1 ); // 绑定端口 socket_bind ( $socket, 0, $port ); // 监听端口 socket_listen ( $socket ); // 声明一个数组,用于存放所有的客户端连接 $clients = array ( $socket ); while ( true ) { $changed_socket = $clients; // 在当前数组中获取活跃的Socket连接,即当前正在发送请求的连接或正在传输数据的连接等 socket_select ( $changed_socket, $null, $null, 0, 10 ); // 判断当前的Socket是否为活跃的Socket,如果是,说明客户端在请求连接 if (in_array ( $socket, $changed_socket )) { echo "client connecting"; // 接受连接 $socket_new = socket_accept ( $socket ); $clients [] = $socket_new; // 发送握手信息 $header = socket_read ( $socket_new, 1024 ); perform_handshaking ( $header, $socket_new, $host, $port ); // 在连接成功后,当前Socket要从活跃Socket列表中删除,否则会陷入死循环 $key = array_search ( $socket, $changed_socket ); unset ( $changed_socket [$key] ); } else { // 不是新连接,是客户端在发送数据 // 服务器开始读取客户端发送的数据 foreach ( $changed_socket as $v ) { while ( socket_recv ( $v, $buf, 1024, 0 ) >= 1 ) { // 解包数据 $received_text = unmask ( $buf ); // 将数据解包后转成JSON对象 $msgJson = json_decode ( $received_text ); // 读取数据 $namer = $msgJson->namer; $content = $msgJson->content; // 将数据进行编码 $message = mask ( json_encode ( [ 'namer' => $namer, 'content' => $content, 'type' => 'usermsg' ] ) ); // 广播编码后的数据。服务器进行广播的消息会触发客户端的onmessage事件 send_message ( $message ); // 跳出foreach循环 break 2; } // 删除已经关闭的Socket $buf = @socket_read ( $v, 1024, PHP_NORMAL_READ ); if ($buf === false) { $key = array_search ( $v, $clients ); socket_getpeername ( $v, $ip ); unset ( $clients [$key] ); $msg = mask ( json_encode ( [ 'type' => 'system', 'content' => $ip . "已经下线。" ] ) ); send_message ( $msg ); } } } } // 发送消息的方法 function send_message($msg) { global $clients; foreach ( $clients as $changed_socket ) { @socket_write ( $changed_socket, $msg, strlen ( $msg ) ); } return true; } // 以下3个函数,我们只需了解总体结构即可。在有需要时可以直接使用 // 解码数据。服务器解码客户端发送过来的数据 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" . "Sec-WebSocket-Accept:$secAccept\r\n\r\n"; socket_write ( $client_conn, $upgrade, strlen ( $upgrade ) ); }
内容总结
以上是互联网集市为您收集整理的php使用Socket实现聊天室功能(书中的代码)全部内容,希望文章能够帮你解决php使用Socket实现聊天室功能(书中的代码)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。