WebSocketd + php 在windows上的用法

    技术2023-05-15  103

    WebSocketd + php 在windows上的用法

    1. 下载WebSocketd的windows版本,http://websocketd.com/

    2. 编写服务端脚本,保存为server.php

    /** 注意: 1. 如果不是循环,会连一下就断掉 2. 如果不是从 STDIN 拿数据,echo 后一定要加上 "\r\n" 或者 PHP_EOL,否则不输出, 从STDIN那到的数据,已经带换行了,没有必要再输出额外的换行 */ while(true){ $clientSend = fgets(STDIN);//从标准输入获取客户端发送的数据 if($clientSend){ echo $clientSend;//输出到标准输出,返回给客户端 //echo PHP_EOL; } $clientSend = str_replace(array("\r\n", "\r", "\n"), "", $clientSend); if($clientSend=='#close#'){ // 满足指定条件,则服务器主动关闭连接 exit('closed'); } }

    3. 启动WebSocket服务,注意自己环境下的路径

    websocketd.exe --port 8848 php ./server.php

    4. 客户端代码

    <html> <head> <meta charset="UTF-8"> </head> <body> WebSocket Test <p><input type="text" id="server_addr" value="ws://localhost:8848"></p> <p><button id='connect'>点击连接</button>&nbsp;&nbsp;<button id='close'>点击断开</button></p> <p><input type="text" id="msg" value=""></p> <p><button id='send'>发送</button></p> <textarea rows="20" cols="50" style="overflow:scroll;" id="log"></textarea> <p><button id='clear'>清空日志</button></p> <!--<div id="log">--> <!--</div>--> <script> var websocket; var log; document.getElementById("connect").onclick=function(){ var addr = document.getElementById('server_addr').value; websocket = new WebSocket(addr); websocket.onopen = function(evt) { onOpen(evt) }; websocket.onclose = function(evt) { onClose(evt) }; websocket.onmessage = function(evt) { onMessage(evt) }; websocket.onerror = function(evt) { onError(evt) }; } document.getElementById("close").onclick=function(){ websocket.close(); } document.getElementById("send").onclick=function(){ websocket.send(document.getElementById("msg").value); } document.getElementById("clear").onclick=function(){ log.value=''; } function onOpen(e){ writeToScreen('connected'); } function onClose(e){ writeToScreen('closed'); } function onMessage(e){ console.log(e); writeToScreen(e.data); } function onError(e){ } function writeToScreen(message) { /* var pre = document.createElement("p"); pre.style.wordWrap = "break-word"; pre.innerHTML = message; */ log.value = log.value+message+"\r\n"; } function init(){ log = document.getElementById("log"); } init(); </script> </body> </html>

    5. 体验连接,断开,发送消息功能

    答疑解惑

    服务端如何主动关闭连接?

    满足指定条件,直接退出脚本即可,例如:

    if($clientSend=='#close#'){ // 满足指定条件,则服务器主动关闭连接 exit('closed'); }

    服务端如何检测到客户端关闭连接?

    我想在客户端关闭连接的时候清理一些数据,目前在服务端通过不断输入日志到文件测试方法,当客户端调用WebSocket.close()方法时,日志文件中的内容也不更新了,这说明服务端脚本也停掉了。 目前想到的方法是,当客户端想要关闭连接时,不要调用WebSocket.close()方法,而是发送一个关闭的消息告诉服务器,当服务端完成清理工作后再由服务端关闭连接。不过这样肯定是有问题的,我们不能保证别人也遵守这个约定。 正规的做法是在脚本中检测信号,windwos上不支持。

    服务端如何区分所有连接的客户端

    WebSocketd是以独立的进程处理每个客户端连接,所以无法在不借助其它方法的情况下区分客户端,我们可以用数据库记录信息来区分客户端,每个客户端都需要登录,然后分配以token,之后就用token来区分客户端,我们可以在服务端程序中通过数据库操作,给每个客户端发送他们自己的消息。

    如何获取地址栏传过来的参数

    例如:ws://localhost:8848?a=1,要获取a的值。 在服务端的代码中执行下面的语句,你会发现,你已经获取到它了。 echo $_ENV['QUERY_STRING'].PHP_EOL;

    Processed: 0.021, SQL: 9