需求:就像饿了么后台,一有订单,就马上提醒。
看了网上很多,都不太明白该怎弄。
原理差不多是客户端js建立长连接,有人下了单,后台直接访问服务端,服务端再反馈给客户端。
不太明白的是,比如说张三登录自己的店铺,建立连接,端口888,有人在张三店铺下了订单,服务端知道了以后,是通过什么流程,把信息再通过888端口反馈给线上的张三。
需求:就像饿了么后台,一有订单,就马上提醒。
看了网上很多,都不太明白该怎弄。
原理差不多是客户端js建立长连接,有人下了单,后台直接访问服务端,服务端再反馈给客户端。
不太明白的是,比如说张三登录自己的店铺,建立连接,端口888,有人在张三店铺下了订单,服务端知道了以后,是通过什么流程,把信息再通过888端口反馈给线上的张三。
贴一段代码,实现了websocket的功能
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.CopyOnWriteArraySet;
@Component
@ServerEndpoint("/webSocket")
@Slf4j
public class WebSocket {
private Session session;
private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this);
log.info("【websocket消息】有新的连接, 总数:{}", webSocketSet.size());
}
@OnClose
public void onClose() {
webSocketSet.remove(this);
log.info("【websocket消息】连接断开, 总数:{}", webSocketSet.size());
}
@OnMessage
public void onMessage(String message) {
log.info("【websocket消息】收到客户端发来的消息:{}", message);
}
public void sendMessage(String message) {
for (WebSocket webSocket: webSocketSet) {
log.info("【websocket消息】广播消息, message={}", message);
try {
webSocket.session.getBasicRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
前台页面接收的demo
<script>
var websocket = null;
if('WebSocket' in window) {
websocket = new WebSocket('ws://xx/webSocket');
}else {
alert('该浏览器不支持websocket!');
}
websocket.onopen = function (event) {
console.log('建立连接');
}
websocket.onclose = function (event) {
console.log('连接关闭');
}
websocket.onmessage = function (event) {
console.log('收到消息:' + event.data)
//弹窗提醒, 播放音乐
$('#myModal').modal('show');
document.getElementById('notice').play();
}
websocket.onerror = function () {
alert('websocket通信发生错误!');
}
window.onbeforeunload = function () {
websocket.close();
}
</script>
<?php
error_reporting(E_ALL);
set_time_limit(0);
echo "<h2>TCP/IP Connection</h2>\n";
$port = 8888;
$ip = "127.0.0.1";
/*
+-------------------------------
* @socket连接整个过程
+-------------------------------
* @socket_create
* @socket_connect
* @socket_write
* @socket_read
* @socket_close
+--------------------------------
*/
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket < 0) {
echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
}else {
echo "OK.\n";
}
echo "试图连接 '$ip' 端口 '$port'...\n";
$result = socket_connect($socket, $ip, $port);
if ($result < 0) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
}else {
echo "连接OK\n";
}
$in = "Ho\r\n";
$in .= "first blood\r\n";
$out = '';
if(!socket_write($socket, $in, strlen($in))) {
echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n";
}else {
echo "发送到服务器信息成功!\n";
echo "发送的内容为:<font color='red'>$in</font> <br>";
}
while($out = socket_read($socket, 8192)) {
echo "接收服务器回传信息成功!\n";
echo "接受的内容为:",$out;
}
echo "关闭SOCKET...\n";
socket_close($socket);
echo "关闭OK\n";
error_reporting(E_ALL);
set_time_limit(0);
$ip = '127.0.0.1';
$port = 8888;
// 1. 创建
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if( $socket == FALSE ) {
echo 'create fail: ' . socket_strerror(socket_last_error());
} else {
echo 'OK';
}
// 2. 链接
echo 'we will try to connect ' . $ip .':' . $port . '\r\n----';
$result = socket_connect($socket, $ip, $port);
if ( $result == FALSE) {
}
$in = 'HO ';
$in .= 'first blood--------';
$out = '';
// 3. 向服务端写入
if( !socket_write($socket, $in, strlen($in)) ) {
echo 'write fail: ' . socket_strerror(socket_last_error());
} else {
echo '-----send to server succefully! \r\n----';
echo 'the content is ' . $in;
}
// 3. 从服务端读取
while ( $out = socket_read($socket, 8129) ) {
echo '-----receive from server succefully!\r\n------';
echo 'the contents is ' . $out;
}
// 4. 关闭
echo '----close socket ...';
socket_close($socket);
echo 'closed ok.';
你需要swoole,贴一段swoole官网的代码抛砖引玉,通过swoole_websocket实现。
server端 demo.php
<?php
//官网demo
$server = new swoole_websocket_server("0.0.0.0", 9501);
$server->on('open', function (swoole_websocket_server $server, $request) {
echo "server: handshake success with fd{$request->fd}\n";//$request->fd 是客户端id
});
$server->on('message', function (swoole_websocket_server $server, $frame) {
echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
$server->push($frame->fd, "this is server");//$frame->fd 是客户端id,$frame->data是客户端发送的数据
//服务端向客户端发送数据是用 $server->push( '客户端id' , '内容')
});
$server->on('close', function ($ser, $fd) {
echo "client {$fd} closed\n";
});
$server->start();
?>
client端 index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
<script type="text/javascript">
var exampleSocket = new WebSocket("ws://0.0.0.0:9501");
exampleSocket.onopen = function (event) {
exampleSocket.send("亲爱的服务器!我连上你啦!");
};
exampleSocket.onmessage = function (event) {
console.log(event.data);
}
</script>
</head>
<body>
<input type="text" id="content">
<button onclick="exampleSocket.send( document.getElementById('content').value )">发送</button>
</body>
</html>
php demo.php 启动服务端,然后浏览器访问index.html
1 回答4.1k 阅读✓ 已解决
3 回答1.9k 阅读✓ 已解决
2 回答2.3k 阅读✓ 已解决
2 回答755 阅读✓ 已解决
1 回答1.4k 阅读✓ 已解决
2 回答2.3k 阅读
1 回答695 阅读✓ 已解决
如果你是php的话,无论是想了解过程还是了解相关的开发框架,可以试着看下 workman。
http://www.workerman.net/
你描述的流程其实可以类比聊天程序。
用户在下单或者是进行了其他操作时候,在后台进行消息的转发,比如我在张三发送的消息,我将消息转发,在通过websocket发送给张三。
这其中,实际上就是,用户下单,ajax传到后台,后台经过一部分处理,发现应当传递给用户张三,发现张三连接着websocket,然后就转发过去。
会涉及websocket消息的用户分组等内容