这篇文章上次修改于 3296 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
1、需求
做一个竞拍模块,需要在页面实时显示最新的竞拍价格
2、思路
使用php的swoole提供的websocket可以很好的解决此需求
1、进入页面,和服务端建立socket长链接
2、链接成功,把返回的客户端标识id,当前业务id 发到sockets服务端,存在redis里面做关系映射
3、当业务id有最新的竞拍出价时,从redis里面读取所有的socket客户端链接标识id,循环推送到客户端上
3、服务端代码示列
<?php
/**
* swoole websocket 测试
*
*/
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->select(0);
$server = new swoole_websocket_server("0.0.0.0", 2345);
$server->set(array(
'worker_num' => 4, //worker process num
'backlog' => 128, //listen backlog
'max_request' => 50,
'dispatch_mode'=>1,
));
$server->on('Open', function ($server, $req) {
echo "server: handshake success with fd{$req->fd}\n";
});
$globalServer = null;
$reqfd = null;
$server->on('Message',function( $serv, $frame ){
global $server;
global $globalServer;
$globalServer = $server;
global $reqfd;
$reqfd = $frame->fd;
global $redis;
//web页面注册registerid
if(stripos($frame->data,'transId_') !== false){
$transId = explode( '_', $frame->data );
$fd = $redis->get('100_'.$transId[1] );
if($fd != null){
$fd = json_decode($fd,true);
}
$fd[$reqfd] = $reqfd;
$redis->set( '100_'.$transId[1], json_encode($fd) );
}
//服务端请求更新数据,这里是websocket方式
if(stripos($frame->data,'refresh_') !== false){
$transId = explode( '_', $frame->data );
$fd = $redis->get( '100_'.$transId[1] );
if($fd != null){
$fd = json_decode($fd,true);
}
$err = 0;
foreach( $fd as $f => $d ){
$res = @$server->push( $f, 200 );
if($res === false){
unset($fd[$f]);
$err++;
}
}
if($err){
$fd = json_encode($fd);
$redis->set( '100_'.$transId[1], $fd );
}
}
});
$server->on('Close', function ($server, $fd) {
echo "connection close: " . $fd;
});
$server->start();
4、需要更新竞拍价格的客户端页面
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html>
<head>
<title>WebSocket 测试</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<h1>价格:</h1>
<h3 id="money" >0</h3>
</div>
<script type="text/javascript">
var ws = new WebSocket("ws://114.*.*.*:2345");
ws.onopen = function ( evt ){
ws.send( "transId_1" );
};
ws.onerror = function( evt ){
console.log( '错误信息:' );
console.log( evt );
}
ws.onclose = function( evt ){
console.log( '已关闭' );
}
ws.onmessage = function(evt) {
document.getElementById('money').textContent = evt.data;
console.log( evt );
}
window.onbeforeunload = function(){
alert('确定关闭?');
}
</script>
</body>
</html>
5、通知页面更新测页面
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>发送消息</div>
<script type="text/javascript">
var ws = new WebSocket("ws://114.*.*.*:2345");
ws.onopen = function ( evt ){
console.log( evt );
ws.send( "refresh_1" );
};
</script>
</body>
</html>
只有一条评论 (QwQ)