WebSocket Server with SSL example app
This commit is contained in:
parent
2e3971953b
commit
3b0eb64f1c
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2010 Red Hat, Inc.
|
||||
*
|
||||
* Red Hat licenses this file to you 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.jboss.netty.example.http.websocketx.sslserver;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jboss.netty.bootstrap.ServerBootstrap;
|
||||
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
|
||||
|
||||
/**
|
||||
* A HTTP server which serves Web Socket requests at:
|
||||
*
|
||||
* https://localhost:8081/websocket
|
||||
*
|
||||
* Open your browser at https://localhost:8081/, then the demo page will be
|
||||
* loaded and a Web Socket connection will be made automatically.
|
||||
*
|
||||
* This server illustrates support for the different web socket specification
|
||||
* versions and will work with:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Safari 5+ (draft-ietf-hybi-thewebsocketprotocol-00)
|
||||
* <li>
|
||||
* <li>Chrome 6-13 (draft-ietf-hybi-thewebsocketprotocol-00)
|
||||
* <li>
|
||||
* <li>Chrome 14+ (draft-ietf-hybi-thewebsocketprotocol-10)
|
||||
* <li>
|
||||
* <li>Firefox 7+ (draft-ietf-hybi-thewebsocketprotocol-10)
|
||||
* <li>
|
||||
* </ul>
|
||||
*
|
||||
* @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
|
||||
* @author <a href="http://gleamynode.net/">Trustin Lee</a>
|
||||
* @author <a href="http://www.veebsbraindump.com/">Vibul Imtarnasan</a>
|
||||
*
|
||||
* @version $Rev$, $Date$
|
||||
*/
|
||||
public class WebSocketSslServer {
|
||||
public static void main(String[] args) {
|
||||
ConsoleHandler ch = new ConsoleHandler();
|
||||
ch.setLevel(Level.FINE);
|
||||
Logger.getLogger("").addHandler(ch);
|
||||
Logger.getLogger("").setLevel(Level.FINE);
|
||||
|
||||
// Configure the server.
|
||||
ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
|
||||
Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
|
||||
|
||||
// Set up the event pipeline factory.
|
||||
bootstrap.setPipelineFactory(new WebSocketSslServerPipelineFactory());
|
||||
|
||||
// Bind and start to accept incoming connections.
|
||||
bootstrap.bind(new InetSocketAddress(8081));
|
||||
|
||||
System.out.println("Web Socket Server started on 8081. Open your browser and navigate to https://localhost:8081/");
|
||||
}
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2010 Red Hat, Inc.
|
||||
*
|
||||
* Red Hat licenses this file to you 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.jboss.netty.example.http.websocketx.sslserver;
|
||||
|
||||
import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
|
||||
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
|
||||
import static org.jboss.netty.handler.codec.http.HttpMethod.*;
|
||||
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
|
||||
import static org.jboss.netty.handler.codec.http.HttpVersion.*;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.jboss.netty.buffer.ChannelBuffers;
|
||||
import org.jboss.netty.channel.ChannelFuture;
|
||||
import org.jboss.netty.channel.ChannelFutureListener;
|
||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||
import org.jboss.netty.channel.ExceptionEvent;
|
||||
import org.jboss.netty.channel.MessageEvent;
|
||||
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
|
||||
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
||||
import org.jboss.netty.handler.codec.http.HttpHeaders;
|
||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||
import org.jboss.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
|
||||
import org.jboss.netty.handler.codec.http.websocketx.PingWebSocketFrame;
|
||||
import org.jboss.netty.handler.codec.http.websocketx.PongWebSocketFrame;
|
||||
import org.jboss.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
||||
import org.jboss.netty.handler.codec.http.websocketx.WebSocketFrame;
|
||||
import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
|
||||
import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
|
||||
import org.jboss.netty.logging.InternalLogger;
|
||||
import org.jboss.netty.logging.InternalLoggerFactory;
|
||||
import org.jboss.netty.util.CharsetUtil;
|
||||
|
||||
/**
|
||||
* Handles handshakes and messages
|
||||
*
|
||||
* @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
|
||||
* @author <a href="http://gleamynode.net/">Trustin Lee</a>
|
||||
* @author <a href="http://www.veebsbraindump.com/">Vibul Imtarnasan</a>
|
||||
*
|
||||
* @version $Rev$, $Date$
|
||||
*/
|
||||
public class WebSocketSslServerHandler extends SimpleChannelUpstreamHandler {
|
||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketSslServerHandler.class);
|
||||
|
||||
private static final String WEBSOCKET_PATH = "/websocket";
|
||||
|
||||
private WebSocketServerHandshaker handshaker = null;
|
||||
|
||||
@Override
|
||||
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
|
||||
Object msg = e.getMessage();
|
||||
if (msg instanceof HttpRequest) {
|
||||
handleHttpRequest(ctx, (HttpRequest) msg);
|
||||
} else if (msg instanceof WebSocketFrame) {
|
||||
handleWebSocketFrame(ctx, (WebSocketFrame) msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
|
||||
// Allow only GET methods.
|
||||
if (req.getMethod() != GET) {
|
||||
sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the demo page and favicon.ico
|
||||
if (req.getUri().equals("/")) {
|
||||
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);
|
||||
|
||||
ChannelBuffer content = WebSocketSslServerIndexPage.getContent(getWebSocketLocation(req));
|
||||
|
||||
res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8");
|
||||
setContentLength(res, content.readableBytes());
|
||||
|
||||
res.setContent(content);
|
||||
sendHttpResponse(ctx, req, res);
|
||||
return;
|
||||
} else if (req.getUri().equals("/favicon.ico")) {
|
||||
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND);
|
||||
sendHttpResponse(ctx, req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handshake
|
||||
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
|
||||
this.getWebSocketLocation(req), null, false);
|
||||
this.handshaker = wsFactory.newHandshaker(ctx, req);
|
||||
if (this.handshaker == null) {
|
||||
wsFactory.sendUnsupportedWebSocketVersionResponse(ctx);
|
||||
} else {
|
||||
this.handshaker.executeOpeningHandshake(ctx, req);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
|
||||
|
||||
// Check for closing frame
|
||||
if (frame instanceof CloseWebSocketFrame) {
|
||||
this.handshaker.executeClosingHandshake(ctx, (CloseWebSocketFrame) frame);
|
||||
return;
|
||||
} else if (frame instanceof PingWebSocketFrame) {
|
||||
ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData()));
|
||||
return;
|
||||
} else if (!(frame instanceof TextWebSocketFrame)) {
|
||||
throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass()
|
||||
.getName()));
|
||||
}
|
||||
|
||||
// Send the uppercase string back.
|
||||
String request = ((TextWebSocketFrame) frame).getText();
|
||||
logger.debug(String.format("Channel %s received %s", ctx.getChannel().getId(), request));
|
||||
ctx.getChannel().write(new TextWebSocketFrame(request.toUpperCase()));
|
||||
}
|
||||
|
||||
private void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) {
|
||||
// Generate an error page if response status code is not OK (200).
|
||||
if (res.getStatus().getCode() != 200) {
|
||||
res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8));
|
||||
setContentLength(res, res.getContent().readableBytes());
|
||||
}
|
||||
|
||||
// Send the response and close the connection if necessary.
|
||||
ChannelFuture f = ctx.getChannel().write(res);
|
||||
if (!isKeepAlive(req) || res.getStatus().getCode() != 200) {
|
||||
f.addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
|
||||
e.getCause().printStackTrace();
|
||||
e.getChannel().close();
|
||||
}
|
||||
|
||||
private String getWebSocketLocation(HttpRequest req) {
|
||||
return "wss://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010 Red Hat, Inc.
|
||||
*
|
||||
* Red Hat licenses this file to you 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.jboss.netty.example.http.websocketx.sslserver;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.jboss.netty.buffer.ChannelBuffers;
|
||||
import org.jboss.netty.util.CharsetUtil;
|
||||
|
||||
|
||||
/**
|
||||
* Generates the demo HTML page which is served at http://localhost:8080/
|
||||
*
|
||||
* @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
|
||||
* @author <a href="http://gleamynode.net/">Trustin Lee</a>
|
||||
* @author <a href="http://www.veebsbraindump.com/">Vibul Imtarnasan</a>
|
||||
*
|
||||
* @version $Rev$, $Date$
|
||||
*/
|
||||
public class WebSocketSslServerIndexPage {
|
||||
|
||||
private static final String NEWLINE = "\r\n";
|
||||
|
||||
public static ChannelBuffer getContent(String webSocketLocation) {
|
||||
return ChannelBuffers.copiedBuffer(
|
||||
"<html><head><title>Web Socket Test</title></head>" + NEWLINE +
|
||||
"<body>" + NEWLINE +
|
||||
"<script type=\"text/javascript\">" + NEWLINE +
|
||||
"var socket;" + NEWLINE +
|
||||
"if (!window.WebSocket) {" + NEWLINE +
|
||||
" window.WebSocket = window.MozWebSocket;" + NEWLINE +
|
||||
"}" + NEWLINE +
|
||||
"if (window.WebSocket) {" + NEWLINE +
|
||||
" socket = new WebSocket(\"" + webSocketLocation + "\");" + NEWLINE +
|
||||
" socket.onmessage = function(event) { var ta = document.getElementById('responseText'); ta.value = ta.value + '\\n' + event.data };" + NEWLINE +
|
||||
" socket.onopen = function(event) { var ta = document.getElementById('responseText'); ta.value = \"Web Socket opened!\"; };" + NEWLINE +
|
||||
" socket.onclose = function(event) { var ta = document.getElementById('responseText'); ta.value = ta.value + \"Web Socket closed\"; };" + NEWLINE +
|
||||
"} else {" + NEWLINE +
|
||||
" alert(\"Your browser does not support Web Socket.\");" + NEWLINE +
|
||||
"}" + NEWLINE +
|
||||
"" + NEWLINE +
|
||||
"function send(message) {" + NEWLINE +
|
||||
" if (!window.WebSocket) { return; }" + NEWLINE +
|
||||
" if (socket.readyState == WebSocket.OPEN) {" + NEWLINE +
|
||||
" socket.send(message);" + NEWLINE +
|
||||
" } else {" + NEWLINE +
|
||||
" alert(\"The socket is not open.\");" + NEWLINE +
|
||||
" }" + NEWLINE +
|
||||
"}" + NEWLINE +
|
||||
"</script>" + NEWLINE +
|
||||
"<form onsubmit=\"return false;\">" + NEWLINE +
|
||||
"<input type=\"text\" name=\"message\" value=\"Hello, World!\"/>" +
|
||||
"<input type=\"button\" value=\"Send Web Socket Data\" onclick=\"send(this.form.message.value)\" />" + NEWLINE +
|
||||
"<h3>Output</h3>" + NEWLINE +
|
||||
"<textarea id=\"responseText\" style=\"width: 500px; height:300px;\"></textarea>" + NEWLINE +
|
||||
"</form>" + NEWLINE +
|
||||
"</body>" + NEWLINE +
|
||||
"</html>" + NEWLINE,
|
||||
CharsetUtil.US_ASCII);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2010 Red Hat, Inc.
|
||||
*
|
||||
* Red Hat licenses this file to you 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.jboss.netty.example.http.websocketx.sslserver;
|
||||
|
||||
import static org.jboss.netty.channel.Channels.*;
|
||||
|
||||
import javax.net.ssl.SSLEngine;
|
||||
|
||||
import org.jboss.netty.channel.ChannelPipeline;
|
||||
import org.jboss.netty.channel.ChannelPipelineFactory;
|
||||
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
|
||||
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
|
||||
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import org.jboss.netty.handler.ssl.SslHandler;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
|
||||
* @author <a href="http://gleamynode.net/">Trustin Lee</a>
|
||||
* @author <a href="http://www.veebsbraindump.com/">Vibul Imtarnasan</a>
|
||||
*
|
||||
* @version $Rev$, $Date$
|
||||
*/
|
||||
public class WebSocketSslServerPipelineFactory implements ChannelPipelineFactory {
|
||||
@Override
|
||||
public ChannelPipeline getPipeline() throws Exception {
|
||||
// Create a default pipeline implementation.
|
||||
ChannelPipeline pipeline = pipeline();
|
||||
|
||||
SSLEngine engine = WebSocketSslServerSslContext.getInstance().getServerContext().createSSLEngine();
|
||||
engine.setUseClientMode(false);
|
||||
pipeline.addLast("ssl", new SslHandler(engine));
|
||||
|
||||
pipeline.addLast("decoder", new HttpRequestDecoder());
|
||||
pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
|
||||
pipeline.addLast("encoder", new HttpResponseEncoder());
|
||||
pipeline.addLast("handler", new WebSocketSslServerHandler());
|
||||
return pipeline;
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2009 Red Hat, Inc.
|
||||
*
|
||||
* Red Hat licenses this file to you 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.jboss.netty.example.http.websocketx.sslserver;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.Security;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.jboss.netty.logging.InternalLogger;
|
||||
import org.jboss.netty.logging.InternalLoggerFactory;
|
||||
|
||||
/**
|
||||
* Creates a {@link SSLContext} for just server certificates.
|
||||
*
|
||||
* @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
|
||||
* @author <a href="http://gleamynode.net/">Trustin Lee</a>
|
||||
* @author <a href="http://www.veebsbraindump.com/">Vibul Imtarnasan</a>
|
||||
*
|
||||
* @version $Rev$, $Date$
|
||||
*/
|
||||
public class WebSocketSslServerSslContext {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketSslServerSslContext.class);
|
||||
private static final String PROTOCOL = "TLS";
|
||||
private SSLContext _serverContext;
|
||||
|
||||
/**
|
||||
* Returns the singleton instance for this class
|
||||
*/
|
||||
public static WebSocketSslServerSslContext getInstance() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* SingletonHolder is loaded on the first execution of
|
||||
* Singleton.getInstance() or the first access to SingletonHolder.INSTANCE,
|
||||
* not before.
|
||||
*
|
||||
* See http://en.wikipedia.org/wiki/Singleton_pattern
|
||||
*/
|
||||
private static class SingletonHolder {
|
||||
|
||||
public static final WebSocketSslServerSslContext INSTANCE = new WebSocketSslServerSslContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for singleton
|
||||
*/
|
||||
private WebSocketSslServerSslContext() {
|
||||
try {
|
||||
// Key store (Server side certificate)
|
||||
String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
|
||||
if (algorithm == null) {
|
||||
algorithm = "SunX509";
|
||||
}
|
||||
|
||||
SSLContext serverContext = null;
|
||||
try {
|
||||
String keyStoreFilePath = System.getProperty("keystore.file.path");
|
||||
String keyStoreFilePassword = System.getProperty("keystore.file.password");
|
||||
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
FileInputStream fin = new FileInputStream(keyStoreFilePath);
|
||||
ks.load(fin, keyStoreFilePassword.toCharArray());
|
||||
|
||||
// Set up key manager factory to use our key store
|
||||
// Assume key password is the same as the key store file
|
||||
// password
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
|
||||
kmf.init(ks, keyStoreFilePassword.toCharArray());
|
||||
|
||||
// Initialise the SSLContext to work with our key managers.
|
||||
serverContext = SSLContext.getInstance(PROTOCOL);
|
||||
serverContext.init(kmf.getKeyManagers(), null, null);
|
||||
} catch (Exception e) {
|
||||
throw new Error("Failed to initialize the server-side SSLContext", e);
|
||||
}
|
||||
_serverContext = serverContext;
|
||||
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
logger.error("Error initializing SslContextManager. " + ex.getMessage(), ex);
|
||||
System.exit(1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server context with server side key store
|
||||
*/
|
||||
public SSLContext getServerContext() {
|
||||
return _serverContext;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2009 Red Hat, Inc.
|
||||
*
|
||||
* Red Hat licenses this file to you 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>This package contains an example web socket web server with server SSL.
|
||||
* <p>To run this example, follow the steps below:
|
||||
* <dl>
|
||||
* <dt>Step 1. Generate Your Key</dt>
|
||||
* <dd>
|
||||
* <code>keytool -genkey -keystore mySrvKeystore -keyalg RSA</code>.
|
||||
* Make sure that you set the key password to be the same the key file password.
|
||||
* </dd>
|
||||
* <dt>Step 2. Specify your key store file and password as system properties</dt>
|
||||
* <dd>
|
||||
* <code>-Dkeystore.file.path=<path to mySrvKeystore> -Dkeystore.file.password=<password></code>
|
||||
* </dd>
|
||||
* <dt>Step 3. Run WebSocketSslServer as a Java application</dt>
|
||||
* <dd>
|
||||
* Once started, you can test the web server against your browser by navigating to https://localhost:8081/
|
||||
* </dd>
|
||||
* </dl>
|
||||
* <p>To find out more about setting up key stores, refer to this
|
||||
* <a href="http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html">giude</a>.
|
||||
*/
|
||||
package org.jboss.netty.example.http.websocketx.sslserver;
|
||||
|
Loading…
Reference in New Issue
Block a user