/**
* Copyright © 2016-2017 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.extensions.api.plugins.handlers;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.extensions.api.plugins.PluginContext;
import org.thingsboard.server.extensions.api.plugins.ws.PluginWebsocketSessionRef;
import org.thingsboard.server.extensions.api.plugins.ws.SessionEvent;
import org.thingsboard.server.extensions.api.plugins.ws.WsSessionMetaData;
import org.thingsboard.server.extensions.api.plugins.ws.msg.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author Andrew Shvayka
*/
@Slf4j
public class DefaultWebsocketMsgHandler implements WebsocketMsgHandler {
protected final ObjectMapper jsonMapper = new ObjectMapper();
protected final Map<String, WsSessionMetaData> wsSessionsMap = new HashMap<>();
@Override
public void process(PluginContext ctx, PluginWebsocketMsg<?> wsMsg) {
PluginWebsocketSessionRef sessionRef = wsMsg.getSessionRef();
if (log.isTraceEnabled()) {
log.trace("[{}] Processing: {}", sessionRef.getSessionId(), wsMsg);
} else {
log.debug("[{}] Processing: {}", sessionRef.getSessionId(), wsMsg.getClass().getSimpleName());
}
if (wsMsg instanceof SessionEventPluginWebSocketMsg) {
handleWebSocketSessionEvent(ctx, sessionRef, (SessionEventPluginWebSocketMsg) wsMsg);
} else if (wsMsg instanceof TextPluginWebSocketMsg || wsMsg instanceof BinaryPluginWebSocketMsg) {
handleWebSocketMsg(ctx, sessionRef, wsMsg);
} else if (wsMsg instanceof PongPluginWebsocketMsg) {
handleWebSocketPongEvent(ctx, sessionRef);
}
}
protected void handleWebSocketMsg(PluginContext ctx, PluginWebsocketSessionRef sessionRef, PluginWebsocketMsg<?> wsMsg) {
throw new RuntimeException("Web-sockets are not supported by current plugin!");
}
protected void cleanupWebSocketSession(PluginContext ctx, String sessionId) {
}
protected void handleWebSocketSessionEvent(PluginContext ctx, PluginWebsocketSessionRef sessionRef, SessionEventPluginWebSocketMsg wsMsg) {
String sessionId = sessionRef.getSessionId();
SessionEvent event = wsMsg.getPayload();
log.debug("[{}] Processing: {}", sessionId, event);
switch (event.getEventType()) {
case ESTABLISHED:
wsSessionsMap.put(sessionId, new WsSessionMetaData(sessionRef));
break;
case ERROR:
log.debug("[{}] Unknown websocket session error: {}. ", sessionId, event.getError().get());
break;
case CLOSED:
wsSessionsMap.remove(sessionId);
cleanupWebSocketSession(ctx, sessionId);
break;
}
}
protected void handleWebSocketPongEvent(PluginContext ctx, PluginWebsocketSessionRef sessionRef) {
String sessionId = sessionRef.getSessionId();
WsSessionMetaData sessionMD = wsSessionsMap.get(sessionId);
if (sessionMD != null) {
log.debug("[{}] Updating session metadata: {}", sessionId, sessionRef);
sessionMD.setSessionRef(sessionRef);
sessionMD.setLastActivityTime(System.currentTimeMillis());
}
}
public void clear(PluginContext ctx) {
wsSessionsMap.values().forEach(v -> {
try {
ctx.close(v.getSessionRef());
} catch (IOException e) {
log.debug("[{}] Failed to close session: {}", v.getSessionRef().getSessionId(), e.getMessage(), e);
}
});
wsSessionsMap.clear();
}
}