1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.web.socket.adapter.standard;
18
19 import java.nio.ByteBuffer;
20 import javax.websocket.CloseReason;
21 import javax.websocket.Endpoint;
22 import javax.websocket.EndpointConfig;
23 import javax.websocket.MessageHandler;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import org.springframework.util.Assert;
29 import org.springframework.web.socket.BinaryMessage;
30 import org.springframework.web.socket.CloseStatus;
31 import org.springframework.web.socket.PongMessage;
32 import org.springframework.web.socket.TextMessage;
33 import org.springframework.web.socket.WebSocketHandler;
34 import org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator;
35
36
37
38
39
40
41
42 public class StandardWebSocketHandlerAdapter extends Endpoint {
43
44 private static final Log logger = LogFactory.getLog(StandardWebSocketHandlerAdapter.class);
45
46 private final WebSocketHandler handler;
47
48 private final StandardWebSocketSession wsSession;
49
50
51 public StandardWebSocketHandlerAdapter(WebSocketHandler handler, StandardWebSocketSession wsSession) {
52 Assert.notNull(handler, "handler must not be null");
53 Assert.notNull(wsSession, "wsSession must not be null");
54 this.handler = handler;
55 this.wsSession = wsSession;
56 }
57
58
59 @Override
60 public void onOpen(final javax.websocket.Session session, EndpointConfig config) {
61
62 this.wsSession.initializeNativeSession(session);
63
64 if (this.handler.supportsPartialMessages()) {
65 session.addMessageHandler(new MessageHandler.Partial<String>() {
66 @Override
67 public void onMessage(String message, boolean isLast) {
68 handleTextMessage(session, message, isLast);
69 }
70 });
71 session.addMessageHandler(new MessageHandler.Partial<ByteBuffer>() {
72 @Override
73 public void onMessage(ByteBuffer message, boolean isLast) {
74 handleBinaryMessage(session, message, isLast);
75 }
76 });
77 }
78 else {
79 session.addMessageHandler(new MessageHandler.Whole<String>() {
80 @Override
81 public void onMessage(String message) {
82 handleTextMessage(session, message, true);
83 }
84 });
85 session.addMessageHandler(new MessageHandler.Whole<ByteBuffer>() {
86 @Override
87 public void onMessage(ByteBuffer message) {
88 handleBinaryMessage(session, message, true);
89 }
90 });
91 }
92
93 session.addMessageHandler(new MessageHandler.Whole<javax.websocket.PongMessage>() {
94 @Override
95 public void onMessage(javax.websocket.PongMessage message) {
96 handlePongMessage(session, message.getApplicationData());
97 }
98 });
99
100 try {
101 this.handler.afterConnectionEstablished(this.wsSession);
102 }
103 catch (Throwable t) {
104 ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
105 return;
106 }
107 }
108
109 private void handleTextMessage(javax.websocket.Session session, String payload, boolean isLast) {
110 TextMessage textMessage = new TextMessage(payload, isLast);
111 try {
112 this.handler.handleMessage(this.wsSession, textMessage);
113 }
114 catch (Throwable t) {
115 ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
116 }
117 }
118
119 private void handleBinaryMessage(javax.websocket.Session session, ByteBuffer payload, boolean isLast) {
120 BinaryMessage binaryMessage = new BinaryMessage(payload, isLast);
121 try {
122 this.handler.handleMessage(this.wsSession, binaryMessage);
123 }
124 catch (Throwable t) {
125 ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
126 }
127 }
128
129 private void handlePongMessage(javax.websocket.Session session, ByteBuffer payload) {
130 PongMessage pongMessage = new PongMessage(payload);
131 try {
132 this.handler.handleMessage(this.wsSession, pongMessage);
133 }
134 catch (Throwable t) {
135 ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
136 }
137 }
138
139 @Override
140 public void onClose(javax.websocket.Session session, CloseReason reason) {
141 CloseStatus closeStatus = new CloseStatus(reason.getCloseCode().getCode(), reason.getReasonPhrase());
142 try {
143 this.handler.afterConnectionClosed(this.wsSession, closeStatus);
144 }
145 catch (Throwable t) {
146 logger.error("Unhandled error for " + this.wsSession, t);
147 }
148 }
149
150 @Override
151 public void onError(javax.websocket.Session session, Throwable exception) {
152 try {
153 this.handler.handleTransportError(this.wsSession, exception);
154 }
155 catch (Throwable t) {
156 ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
157 }
158 }
159
160 }