我有一个Java桌面应用程序,这个应用程序启动一个用Java编写的安全websocket服务器。现在它正在使用自签名证书,该证书要求Web浏览器用户手动接受自签名证书,以便能够启动与同一websocket服务器的客户端连接。
我有一个类似" mydomain.com"这样的域的SSL证书,我想使用该SSL证书来启动Java Desktop Application的安全websocket。当然,计算机必须将该域指向本地计算机,因此我将127.0.0.1 mydomain.com
添加到我的HOSTS文件(我在Windows中)。即便如此,它也无法正常工作。
所以问题是:
是否可以使用此Java创建安全Websocket服务器 桌面应用程序,以便在我的本地浏览器尝试访问时 wss://mydomain.com/appservices它像往常一样接受证书 (鉴于HOSTS文件修改)?,如果可以,我该怎么办 给出以下示例代码吗?
当前代码的其他信息和示例
以下是在我的Java Desktop App中启动安全websocket服务器的代码:
package com.mydomain.desktopclient.websockets.server;
import com.mydomain.desktopclient.resources.ResourceLoader;
import com.mydomain.desktopclient.websockets.server.endpoint.RequestServerEndpoint;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
import javax.websocket.server.ServerContainer;
import java.net.URL;
public class SecureWebSocketServer {
Server server = null;
public void start() throws Exception {
server = new Server();
int httpsPort = 443;
URL keystore = ResourceLoader.getLocalResourceURL("/resources/misc/keystore/keystore.jks");
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(keystore.toExternalForm());
sslContextFactory.setCertAlias("mydomain.com.key");
sslContextFactory.setKeyStorePassword("keystorepass");
sslContextFactory.setKeyManagerPassword("keymanagerpass");
sslContextFactory.addExcludeProtocols("SSLv3");
sslContextFactory.addExcludeCipherSuites(".*_GCM_.*");
HttpConfiguration httpsConf = new HttpConfiguration();
httpsConf.setSecurePort(httpsPort);
httpsConf.setSecureScheme("https");
httpsConf.addCustomizer(new SecureRequestCustomizer());
ServerConnector httpsConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, "http/1.1"),
new HttpConnectionFactory(httpsConf));
httpsConnector.setHost("mydomain.com");
httpsConnector.setPort(httpsPort);
server.addConnector(httpsConnector);
HandlerList baseHandlers = new HandlerList();
server.setHandler(baseHandlers);
ServletContextHandler context = new ServletContextHandler();
// context.setVirtualHosts(new String[] {"mydomain.com"});
context.setContextPath("/");
baseHandlers.addHandler(context);
// Add WebSocket
ServerContainer jsrContainer = WebSocketServerContainerInitializer.configureContext(context);
jsrContainer.setDefaultMaxSessionIdleTimeout(1000 * 60 * 60 * 24);
jsrContainer.addEndpoint(RequestServerEndpoint.class);
Handler handler = new DefaultHandler();
baseHandlers.addHandler(handler);
server.setDumpAfterStart(true);
server.setDumpBeforeStop(true);
try {
server.start();
server.join();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
public void stop() throws Exception {
if( server != null ){
server.stop();
server = null;
}
}
}
此代码使用jetty-all-9.3.1.v20150714-uber.jar
作为websocket库。
类com.mydomain.desktopclient.resources.ResourceLoader
是一个简单的类,用于从应用程序的jar文件中查找和返回文件作为资源。
如果需要,这是RequestServerEndpoint:
package com.mydomain.desktopclient.websockets.server.endpoint;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.logging.Logger;
@ServerEndpoint(value = "/appservices")
public class RequestServerEndpoint {
private static Logger logger = Logger.getLogger(RequestServerEndpoint.class.getName());
@OnOpen
public void onOpen(Session session) {
logger.info("Connected ... " + session.getId());
}
@OnMessage
public String onMessage(String incommingMessage, Session session) {
logger.info("Received Message: \n\n" + incommingMessage);
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
logger.info(String.format("Session %s closed because of %s", session.getId(), closeReason));
}
}