如何通过Tomcat使用Spark Framework运行WebSockets?

时间:2016-02-22 11:21:52

标签: java tomcat websocket spark-java

我从https://sparktutorials.github.io/2015/11/08/spark-websocket-chat.html获取了一个示例,并希望将其作为war部署到Tomcat以在Web服务器上运行它。我已经找到了几个基本请求的示例(例如get,对于Ex。)但这种方式不适用于Web套接字。

public class Chat implements SparkApplication{

static Map<Session, String> userUsernameMap = new HashMap<>();
static int nextUserNumber = 1; //Used for creating the next username

public static void main(String[] args) {
    new Chat().init();
}

//Sends a message from one user to all users, along with a list of current usernames
public static void broadcastMessage(String sender, String message) {
    userUsernameMap.keySet().stream().filter(Session::isOpen).forEach(session -> {
        try {
            session.getRemote().sendString(String.valueOf(new JSONObject()
                    .put("userMessage", createHtmlMessageFromSender(sender, message))
                    .put("userlist", userUsernameMap.values())
            ));
        } catch (Exception e) {
            e.printStackTrace();
        }
    });
}

//Builds a HTML element with a sender-name, a message, and a timestamp,
private static String createHtmlMessageFromSender(String sender, String message) {
    return article().with(
            b(sender + " says:"),
            p(message),
            span().withClass("timestamp").withText(new SimpleDateFormat("HH:mm:ss").format(new Date()))
    ).render();
}

@Override
public void init() {
    String route = "/chat";
    webSocket(route, ChatWebSocketHandler.class);
}
}

当我运行它时,我得到了

  

org.apache.catalina.core.StandardContext.filterStart异常启动过滤器SparkFilter    java.lang.IllegalStateException:WebSockets仅在嵌入式服务器

中受支持

webSocket(route, ChatWebSocketHandler.class);方法中的void init()行。

如果smth取决于我的web.xml(我没有改变它),列表就在这里:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<display-name>Messenger</display-name>

<filter>
    <filter-name>SparkFilter</filter-name>
    <filter-class>spark.servlet.SparkFilter</filter-class>
    <init-param>
        <param-name>applicationClass</param-name>
        <param-value>com.barbarian.messenger.Chat</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>SparkFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

如果我把new SparkFilter();放在那条线之前(刚尝试过),我得到了

  

org.apache.catalina.core.StandardContext.filterStart异常启动过滤器SparkFilter    java.lang.IllegalStateException:WebSockets仅在嵌入式服务器

中受支持

在同一条线上。

是否有人有有效运行的想法?

1 个答案:

答案 0 :(得分:3)

基于文档(至少是当前文档):

  

WebSockets仅适用于嵌入式Jetty服务器,必须在常规HTTP路由之前定义......

http://sparkjava.com/documentation.html#websockets

这就是为什么在示例代码(https://github.com/tipsy/spark-websocket)中没有在web.xml中看到任何servlet配置的原因,因为嵌入式Jetty容器可以直接在main方法中运行。它还使用org.eclipse.jetty.websocket.api。*包进行websocket实现。

如果您需要在Tomcat上运行websocket,您可能需要考虑在catalina包中使用WebSocketServlet实现。我在这里找到了示例代码(即使我还没有测试过它):https://gist.github.com/chitan/3063774。希望这会有所帮助。