/**
注意:
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');
}
}
websocketd.exe --port 8848 php ./server.php
<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> <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>
满足指定条件,直接退出脚本即可,例如:
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;