JavaScript客户端与PHP服务器WebSocket连接被拒的修复方案咨询
解决JavaScript WebSocket客户端连接PHP服务器时的"Connection Refused"问题
问题背景
你尝试用JavaScript客户端连接PHP服务器的WebSocket,但一直收到"连接被拒绝"错误——虽然你已经成功在两个PHP脚本间建立了TCP连接,但这和WebSocket完全不是一回事儿,这就是问题的核心!
你的现有代码:
服务器端(PHP)代码
$host = "108.167.140.91"; $port = 5353; set_time_limit(30); // create socket $socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n"); // bind socket to port $result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n"); // start listening for connections $result = socket_listen($socket, 20); // accept incoming connections // spawn another socket to handle communication $spawn = socket_accept($socket) or die("Could not accept incoming connection\n"); socket_write($spawn, "connected", strlen ("connected")); // close sockets socket_close($spawn); socket_close($socket);
客户端(HTML)代码
<html> <script> var socket = new WebSocket("ws://108.167.140.91:5353"); // Open the socket socket.onopen = function(event) { console.log("connected"); // To close the socket.... socket.close() }; </script> </html>
问题根源
你现在的PHP服务器只是一个普通的TCP Socket服务器,而JavaScript的WebSocket对象遵循的是WebSocket协议(RFC 6455)——它需要先通过HTTP握手升级到WebSocket连接,不是直接建立TCP连接就完事了。你的服务器没有处理WebSocket的握手流程,所以客户端发起连接请求时,服务器无法正确响应,最终导致连接被拒绝或失败。
解决方案
1. 手动实现WebSocket握手逻辑
修改你的PHP服务器代码,添加WebSocket握手处理:
$host = "108.167.140.91"; $port = 5353; set_time_limit(0); // 创建TCP socket $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("无法创建socket\n"); socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1); socket_bind($socket, $host, $port) or die("无法绑定socket\n"); socket_listen($socket, 20) or die("监听失败\n"); echo "服务器已启动,等待连接...\n"; while (true) { $client = socket_accept($socket) or die("接受连接失败\n"); // 读取客户端握手请求 $request = socket_read($client, 1024); // 解析握手请求,提取Sec-WebSocket-Key preg_match('#Sec-WebSocket-Key: (.*)\r\n#', $request, $matches); $key = $matches[1]; $acceptKey = base64_encode(sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true)); // 构建握手响应 $response = "HTTP/1.1 101 Switching Protocols\r\n"; $response .= "Upgrade: websocket\r\n"; $response .= "Connection: Upgrade\r\n"; $response .= "Sec-WebSocket-Accept: $acceptKey\r\n\r\n"; // 发送响应完成握手 socket_write($client, $response, strlen($response)); // 测试:发送一个WebSocket帧 $message = "Hello from WebSocket server!"; $frame = chr(0x81) . chr(strlen($message)) . $message; socket_write($client, $frame, strlen($frame)); socket_close($client); } socket_close($socket);
2. 使用成熟的PHP WebSocket库
手动实现WebSocket协议很容易踩坑(比如帧编码、心跳、多客户端管理等),更推荐使用成熟的库,比如:
- Ratchet:专门为PHP打造的异步WebSocket库,支持多客户端、事件驱动,文档完善
- ReactPHP WebSocket:基于ReactPHP的异步WebSocket组件
额外注意事项
- 确保服务器的端口5353没有被防火墙或服务器安全组拦截
- 如果你的网站使用HTTPS,需要用
wss://协议连接,并且配置SSL证书
内容的提问来源于stack exchange,提问作者C. Lang
相关产品推荐
相关产品推荐

