net.apexes.wsonrpc.server.support.JavaWebsocketWsonrpcServer Maven / Gradle / Ivy
/*
* Copyright (c) 2018. , apexes.net. All rights reserved.
*
* http://www.apexes.net
*
*/
package net.apexes.wsonrpc.server.support;
import net.apexes.wsonrpc.core.WebSocketSession;
import net.apexes.wsonrpc.core.WsonrpcConfig;
import net.apexes.wsonrpc.server.PathAcceptor;
import net.apexes.wsonrpc.server.PathAcceptors;
import net.apexes.wsonrpc.server.WsonrpcCloseListener;
import net.apexes.wsonrpc.server.WsonrpcMessageListener;
import net.apexes.wsonrpc.server.WsonrpcOpenListener;
import net.apexes.wsonrpc.server.WsonrpcPingListener;
import net.apexes.wsonrpc.server.WsonrpcRequestInterceptor;
import net.apexes.wsonrpc.server.WsonrpcServer;
import net.apexes.wsonrpc.server.WsonrpcServerBase;
import net.apexes.wsonrpc.server.WsonrpcServerBuilder;
import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketAdapter;
import org.java_websocket.WebSocketImpl;
import org.java_websocket.WebSocketListener;
import org.java_websocket.WebSocketServerFactory;
import org.java_websocket.drafts.Draft;
import org.java_websocket.exceptions.InvalidDataException;
import org.java_websocket.framing.CloseFrame;
import org.java_websocket.framing.Framedata;
import org.java_websocket.framing.PingFrame;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.handshake.ServerHandshakeBuilder;
import org.java_websocket.server.DefaultWebSocketServerFactory;
import org.java_websocket.server.WebSocketServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 基于 {@link org.java_websocket.server.WebSocketServer}的服务端
*
* @author HeDYn
*
*/
public class JavaWebsocketWsonrpcServer {
protected final WebSocketServer websocketServer;
protected final WsonrpcServerBase serverBase;
private final AtomicBoolean isclose = new AtomicBoolean(false);
private WsonrpcPingListener pingListener;
public JavaWebsocketWsonrpcServer(int port) {
this(port, PathAcceptors.rootPath());
}
public JavaWebsocketWsonrpcServer(int port, WsonrpcConfig config) {
this(port, PathAcceptors.rootPath(), config);
}
public JavaWebsocketWsonrpcServer(int port, PathAcceptor pathAcceptor) {
this(port, pathAcceptor, WsonrpcServerBuilder.defaultConfig());
}
public JavaWebsocketWsonrpcServer(int port, PathAcceptor pathAcceptor, WsonrpcConfig config) {
websocketServer = new WebSocketServerAdapter(new InetSocketAddress(port), pathAcceptor, this);
WebSocketServerFactory wsf = new DefaultWebSocketServerFactory() {
@Override
public WebSocketImpl createWebSocket(WebSocketAdapter adapter, Draft draft) {
return new SessionWebSocketImpl(adapter, draft);
}
@Override
public WebSocketImpl createWebSocket(WebSocketAdapter adapter, List draft) {
return new SessionWebSocketImpl(adapter, draft);
}
};
websocketServer.setWebSocketFactory(wsf);
serverBase = new WsonrpcServerBase(config);
}
public WsonrpcServer getWsonrpcServer() {
return serverBase;
}
public WsonrpcPingListener getPingListener() {
return pingListener;
}
public void setPingListener(WsonrpcPingListener pingListener) {
this.pingListener = pingListener;
}
public void setWsonrpcOpenListener(WsonrpcOpenListener listener) {
serverBase.setWsonrpcOpenListener(listener);
}
public void setWsonrpcCloseListener(WsonrpcCloseListener listener) {
serverBase.setWsonrpcCloseListener(listener);
}
public void setWsonrpcMessageListener(WsonrpcMessageListener listener) {
serverBase.setWsonrpcMessageListener(listener);
}
public void setWsonrpcRequestInterceptor(WsonrpcRequestInterceptor interceptor) {
serverBase.setWsonrpcRequestInterceptor(interceptor);
}
public void start() {
isclose.set(false);
try {
websocketServer.start();
} finally {
isclose.set(true);
}
}
public void stop() throws IOException, InterruptedException {
isclose.set(true);
websocketServer.stop();
}
public boolean isRunning() {
return !isclose.get();
}
private static String sessionId(WebSocket websocket) {
if (websocket == null) {
return null;
}
String id;
if (websocket instanceof SessionWebSocketImpl) {
id = ((SessionWebSocketImpl) websocket).getId();
} else {
id = websocket.getRemoteSocketAddress().toString();
}
return id;
}
/**
*
* @author HeDYn
*
*/
private static class SessionWebSocketImpl extends WebSocketImpl {
private final String id = UUID.randomUUID().toString();
public SessionWebSocketImpl(WebSocketListener listener, Draft draft) {
super(listener, draft);
}
public SessionWebSocketImpl(WebSocketListener listener, List drafts) {
super(listener, drafts);
}
String getId() {
return id;
}
}
/**
*
* @author HeDYn
*
*/
private static class WebSocketServerAdapter extends WebSocketServer {
private final JavaWebsocketWsonrpcServer server;
private final PathAcceptor pathAcceptor;
public WebSocketServerAdapter(InetSocketAddress address, PathAcceptor pathAcceptor,
JavaWebsocketWsonrpcServer server) {
super(address);
this.pathAcceptor = pathAcceptor;
this.server = server;
}
@Override
public ServerHandshakeBuilder onWebsocketHandshakeReceivedAsServer(WebSocket websockt, Draft draft,
ClientHandshake request) throws InvalidDataException {
if (pathAcceptor == null || pathAcceptor.accept(request.getResourceDescriptor())) {
return super.onWebsocketHandshakeReceivedAsServer(websockt, draft, request);
}
throw new InvalidDataException(CloseFrame.TLS_ERROR, request.getResourceDescriptor());
}
@Override
public void onOpen(WebSocket websocket, ClientHandshake handshake) {
server.serverBase.onOpen(new JavaWebSocketSessionAdapter(websocket));
}
@Override
public void onStart() {
}
@Override
public void onClose(WebSocket websocket, int code, String reason, boolean remote) {
server.serverBase.onClose(sessionId(websocket));
}
@Override
public void onMessage(WebSocket websocket, String message) {
server.serverBase.onMessage(sessionId(websocket), ByteBuffer.wrap(message.getBytes()));
}
@Override
public void onMessage(WebSocket websocket, ByteBuffer message) {
server.serverBase.onMessage(sessionId(websocket), message);
}
@Override
public void onWebsocketPing(WebSocket websocket, Framedata framedata) {
WsonrpcPingListener listener = server.getPingListener();
if (listener != null) {
listener.onPing(sessionId(websocket), framedata.getPayloadData().array());
}
}
@Override
public void onError(WebSocket websockt, Exception ex) {
if (server.isRunning()) {
server.serverBase.onError(sessionId(websockt), ex);
}
}
}
/**
*
* @author HeDYn
*
*/
private static class JavaWebSocketSessionAdapter implements WebSocketSession {
private static final PingFrame PING_FRAME = new PingFrame();
private final WebSocket websocket;
JavaWebSocketSessionAdapter(WebSocket websocket) {
this.websocket = websocket;
}
@Override
public String getId() {
return sessionId(websocket);
}
@Override
public boolean isOpen() {
return websocket.isOpen();
}
@Override
public void sendBinary(byte[] bytes) {
websocket.send(bytes);
}
@Override
public void ping(byte[] bytes) throws IOException {
PingFrame frame;
if (bytes == null || bytes.length == 0) {
frame = PING_FRAME;
} else {
frame = new PingFrame();
frame.setPayload(ByteBuffer.wrap(bytes));
}
websocket.sendFrame(frame);
}
@Override
public void close() throws IOException {
websocket.close();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy