package org.frameworkset.web.socket.endpoint;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.websocket.CloseReason;
import javax.websocket.CloseReason.CloseCodes;
import javax.websocket.Extension;
import javax.websocket.Session;
import org.frameworkset.http.HttpHeaders;
import org.frameworkset.web.socket.inf.BinaryMessage;
import org.frameworkset.web.socket.inf.CloseStatus;
import org.frameworkset.web.socket.inf.PingMessage;
import org.frameworkset.web.socket.inf.PongMessage;
import org.frameworkset.web.socket.inf.TextMessage;
import org.frameworkset.web.socket.inf.WebSocketExtension;
public class StandardWebSocketSession extends AbstractWebSocketSession<Session> {
private final HttpHeaders handshakeHeaders;
private final InetSocketAddress localAddress;
private final InetSocketAddress remoteAddress;
private Principal user;
private String acceptedProtocol;
private List<WebSocketExtension> extensions;
/**
* Class constructor.
*
* @param headers the headers of the handshake request
* @param attributes attributes from the HTTP handshake to associate with the WebSocket
* session; the provided attributes are copied, the original map is not used.
* @param localAddress the address on which the request was received
* @param remoteAddress the address of the remote client
*/
public StandardWebSocketSession(HttpHeaders headers, Map<String, Object> attributes,
InetSocketAddress localAddress, InetSocketAddress remoteAddress) {
this(headers, attributes, localAddress, remoteAddress, null);
}
/**
* Class constructor that associates a user with the WebSocket session.
*
* @param headers the headers of the handshake request
* @param attributes attributes from the HTTP handshake to associate with the WebSocket session
* @param localAddress the address on which the request was received
* @param remoteAddress the address of the remote client
* @param user the user associated with the session; if {@code null} we'll
* fallback on the user available in the underlying WebSocket session
*/
public StandardWebSocketSession(HttpHeaders headers, Map<String, Object> attributes,
InetSocketAddress localAddress, InetSocketAddress remoteAddress, Principal user) {
super(attributes);
headers = (headers != null) ? headers : new HttpHeaders();
this.handshakeHeaders = HttpHeaders.readOnlyHttpHeaders(headers);
this.localAddress = localAddress;
this.remoteAddress = remoteAddress;
this.user = user;
}
@Override
public String getId() {
checkNativeSessionInitialized();
return getNativeSession().getId();
}
@Override
public URI getUri() {
checkNativeSessionInitialized();
return getNativeSession().getRequestURI();
}
@Override
public HttpHeaders getHandshakeHeaders() {
return this.handshakeHeaders;
}
@Override
public Principal getPrincipal() {
if (this.user != null) {
return this.user;
}
checkNativeSessionInitialized();
return (isOpen() ? getNativeSession().getUserPrincipal() : null);
}
@Override
public InetSocketAddress getLocalAddress() {
return this.localAddress;
}
@Override
public InetSocketAddress getRemoteAddress() {
return this.remoteAddress;
}
@Override
public String getAcceptedProtocol() {
checkNativeSessionInitialized();
return this.acceptedProtocol;
}
@Override
public void setTextMessageSizeLimit(int messageSizeLimit) {
checkNativeSessionInitialized();
getNativeSession().setMaxTextMessageBufferSize(messageSizeLimit);
}
@Override
public int getTextMessageSizeLimit() {
checkNativeSessionInitialized();
return getNativeSession().getMaxTextMessageBufferSize();
}
@Override
public void setBinaryMessageSizeLimit(int messageSizeLimit) {
checkNativeSessionInitialized();
getNativeSession().setMaxBinaryMessageBufferSize(messageSizeLimit);
}
@Override
public int getBinaryMessageSizeLimit() {
checkNativeSessionInitialized();
return getNativeSession().getMaxBinaryMessageBufferSize();
}
@Override
public List<WebSocketExtension> getExtensions() {
checkNativeSessionInitialized();
if(this.extensions == null) {
List<Extension> source = getNativeSession().getNegotiatedExtensions();
this.extensions = new ArrayList<WebSocketExtension>(source.size());
for(Extension e : source) {
this.extensions.add(new StandardToWebSocketExtensionAdapter(e));
}
}
return this.extensions;
}
@Override
public boolean isOpen() {
return (getNativeSession() != null && getNativeSession().isOpen());
}
@Override
public void initializeNativeSession(Session session) {
super.initializeNativeSession(session);
if(this.user == null) {
this.user = session.getUserPrincipal();
}
this.acceptedProtocol = session.getNegotiatedSubprotocol();
}
@Override
protected void sendTextMessage(TextMessage message) throws IOException {
getNativeSession().getBasicRemote().sendText(message.getPayload(), message.isLast());
}
@Override
protected void sendBinaryMessage(BinaryMessage message) throws IOException {
getNativeSession().getBasicRemote().sendBinary(message.getPayload(), message.isLast());
}
@Override
protected void sendPingMessage(PingMessage message) throws IOException {
getNativeSession().getBasicRemote().sendPing(message.getPayload());
}
@Override
protected void sendPongMessage(PongMessage message) throws IOException {
getNativeSession().getBasicRemote().sendPong(message.getPayload());
}
@Override
protected void closeInternal(CloseStatus status) throws IOException {
getNativeSession().close(new CloseReason(CloseCodes.getCloseCode(status.getCode()), status.getReason()));
}
}