心跳机制:客户端每隔一段时间向服务端发送一个特有的心跳消息,每次服务端收到消息后只需将消息返回,此时,若二者还保持连接,则客户端就会收到消息,若没收到,则说明连接断开,此时,客户端就要主动重连,完成一个周期
断线重连:若某时间段内客户端发送了消息,而服务端未返回,则认定为断线;这个时候会触发到websocket中的onclose事件,需要重新连接服务
上代码
pom.xml导入的包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
WebSoketConfig
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Component
public class WebSoketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
后端Util
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.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
@Component
@ServerEndpoint("/webSocket/{uId}")
@Slf4j
public class WebSocketServerUtil {
private Session session;
private static CopyOnWriteArraySet<WebSocketServerUtil > webSocketSet = new CopyOnWriteArraySet<>();
private static ConcurrentHashMap<Long,WebSocketServerUtil > webSocketMap = new ConcurrentHashMap<>();
private Long uId = null;
@OnOpen
public void onOpen(Session session, @PathParam("uId") Long uId){
this.session = session;
this.uId = uId;
if(webSocketMap .containsKey(uId)){
webSocketMap .remove(uId);
webSocketMap .put(uId,this);
}else{
webSocketMap .put(uId,this);
webSocketSet.add(this);
}
log.info("【websocket消息】有新的连接,总数:{}",webSocketMap.size());
}
@OnClose
public void onClose(){
if(webSocketMap.containsKey(uId)){
webSocketMap.remove(uId);
//从set中删除
webSocketSet.remove(this);
}
log.info("【websocket消息】连接断开,总数:{}",webSocketSet.size());
}
@OnMessage
public void onMessage(String message){
log.info("【websocket消息】收到客户端发来的消息:{}",message);
}
public void sendMessage(String message){
try {
this.session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发送自定义消息
* */
public static void sendInfo(String message,Long uId) throws Exception {
//log.info("发送消息到:"+uId+",报文:"+message);
if(webSocketMap.containsKey(uId)){
webSocketMap.get(uId).sendMessage(message);
}else{
log.error("用户"+uId+",不在线!");
throw new Exception("连接已关闭,请刷新页面后重试");
}
}
}
后端消息推送
Long uId = new Long("1");
Map msgMap = new HashMap();
msgMap.put("step",1);
msgMap.put("type",2);
msgMap.put("msg","hello");
WebSocketServerUtil.sendInfo(JsonUtil.toJson(msgMap),uId);
前端JS
/**
* 初始化websocket连接
*/
function initWebSocket() {
let uId = 1;
var websocket = null;
if('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8009/websocket"+uId );
} else {
alert("该浏览器不支持websocket!");
}
websocket.onopen = function(event) {
console.log("建立连接");
websocket.send('Hello WebSockets!');
}
websocket.onclose = function(event) {
console.log('连接关闭')
reconnect(); //尝试重连websocket
}
//建立通信后,监听到后端的数据传递
websocket.onmessage = function(event) {
let data = JSON.parse(event.data);
//业务处理....
if(data.step == 1){
alert(data.msg);
}
}
websocket.onerror = function() {
// notify.warn("websocket通信发生错误!");
// initWebSocket()
}
window.onbeforeunload = function() {
websocket.close();
}
// 重连
function reconnect() {
console.log("正在重连");
// 进行重连
setTimeout(function () {
initWebSocket();
}, 1000);
}
这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式rubyshell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
我想在随机字符串前后添加一个空格。我试过使用"Random_string".center(1,"")但它不起作用。谢谢 最佳答案 我发现这是最优雅的解决方案:padded_string="#{random_string}"走简单的路没有错。 关于ruby-在ruby中的字符串前后添加空格?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/3357897/
IntrductionLibwebsocketsisasimple-to-use,MIT-license,pureClibraryprovidingclientandserverforhttp/1,http/2,websockets,MQTTandotherprotocolsinasecurity-minded,lightweight,configurable,scalableandflexibleway.It’seasytobuildandcross-buildviacmakeandissuitablefortasksfromembeddedRTOSthroughmasscloudservi
我有带有gemwebsocket-rails0.7的Rails3.2应用程序。在开发机上,一切正常在生产环境中,我使用Nginx/1.6作为代理服务器,Unicorn作为http服务器。Thin用于独立模式(在https://github.com/websocket-rails/websocket-rails/wiki/Standalone-Server-Mode之后)。nginx配置:location/websocket{proxy_passhttp://localhost:3001/websocket;proxy_http_version1.1;proxy_set_headerUp
我的第一个想法是这样的:classAbstractBuilderattr_reader:time_takendefbuild_with_timerstarted_at=Time.nowbuild@time_taken=Time.now-started_atenddefbuildraise'Implementthismethodinasubclass'endendclassMyBuilder我怀疑有更好的方法可以提供更好的灵active,例如理想情况下,我想在MyBuilder的实例上调用“build”而不是“build_with_timer”,并且始终记录执行时间。我确实考虑过使用al
目录一、什么是Websocket二、WebSocket部分header介绍三、HTTPVSWebSocket四、什么时候使用WebSockets五、关于SockJS和STOMP一、什么是Websocket根据RFC6455标准,Websocket协议提供了一种标准化的方式在客户端和服务端之间通过TCP连接建立全双工、双向通信渠道。它是一种不同于HTTP的TCP协议,但是被设计为在HTTP基础上运行。Websocket交互始于HTTP请求,该请求会通过HTTPUpgrade请求头去升级请求,进而切换到Websocket协议。请求报文如下:GET/spring-websocket-portfoli
据我了解,在Ruby和Perl之间没有“桥梁”可以让您直接从Ruby调用Perl函数。据我了解,要从Ruby调用Perl程序,只需将其放在反引号中(即result=`./helloWorld.pl`)。但是,这不允许与Perl程序交互(即您不能与提示交互或提供输入)。我的问题如下:有没有什么方法可以从Ruby向Perl程序提供输入(除了参数)?Ruby和Perl之间没有桥梁,我错了吗?在导航提示时与程序的标准输入交互似乎是错误的方式,我正在处理的程序设计良好,并且具有包含适当Perl函数的库。 最佳答案 有Inline::Ruby模
在我采用Ruby语言的过程中,我花了很多时间在IRb中。太棒了!但是,由于我不是很清楚它的功能,并且对Ruby仍然是个“笨蛋”,所以我想知道以下内容:如何在不重新启动IRb的情况下“刷新”session(或者这是不可能的)。如何配置IRb加载一堆源文件“hello.rb”和“hello_objects.rb”,即在启动时?我在这些方面投入了大量工作,如果知道加载这些类的速记,而无需再次为每个类手动键入“加载”,那就太好了。 最佳答案 我不确定是否可以“刷新”session。但是,您可以像这样加载您的类:irb-r'hello.rb'
我开始使用websocket-rails,试图将旧的通知轮询系统(在Ruby2.1/Rails4.0上)转换为更现代的WS系统。我在独立模式下使用WebsocketRails,这是我的配置,基本上是默认配置:WebsocketRails.setupdo|config|config.standalone=trueend我还设置了一个在默认端口上运行的新Redis-这里似乎没有通信问题。在客户端,我添加了websocket-rails的JS,并在尝试打开连接和订阅channel时使用:@dispatcher=newWebSocketRails"localhost:3001/websocke