阻塞连接器不支持Websockets

时间:2013-07-07 17:27:27

标签: java websocket jetty

我做了websocket服务器。它在localhost上的工作,但当我将它部署到服务器时,我得到错误。我找不到解决方案。在localhost上我使用gwt服务器标记为jetty 8.1.7。在部署服务器上有太多的码头8.1.7。

public abstract class WebSocketServlet extends org.eclipse.jetty.websocket.WebSocketServlet implements TextMessageHandler {

private final HashMap<Integer, Socket> sockets = new HashMap<Integer, Socket>();

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if ("WebSockets".equalsIgnoreCase(request.getHeader("Upgrade"))) {
        String origin = request.getHeader("Origin");
        if (origin == null) {
            origin = request.getHeader("Sec-WebSocket-Origin");
        }
        if (!checkOrigin(request, origin)) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
    }
    getServletContext().getNamedDispatcher("default").forward(request, response);
}

public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
    String[] s = request.getPathInfo().split("/");
    String ss = (s.length>1?s[1]:"default");
    return new Socket(this, ss);
}

public void send(int token, String message) throws IOException,   InvalidTokenException {
    Socket socket = sockets.get(token);
    if (socket == null) {
        throw new InvalidTokenException();
    }
    sockets.get(token).sendMessage(message);
}

public boolean isOpened(int token) throws InvalidTokenException {
    Socket socket = sockets.get(token);
    if (socket == null) {
        throw new InvalidTokenException();
    }
    return sockets.get(token).isOpen();
}

public class InvalidTokenException extends Exception {
};

class Socket implements WebSocket.OnTextMessage {
    private Connection _connection;
    private TextMessageHandler handler;
    private String channel;

    public Socket(TextMessageHandler handler, String channel) {
        this.handler = handler;
        this.channel = channel;
    }

    @Override
    public void onClose(int closeCode, String message) {
        sockets.remove(this._connection.hashCode());
        handler.onClose(_connection.hashCode(), channel);
    }

    @Override
    public void onMessage(String data) {
        handler.onMessage(_connection.hashCode(), channel, data);
    }

    public void sendMessage(String data) throws IOException {
        _connection.sendMessage(data);
    }

    public boolean isOpen() {
        return _connection.isOpen();
    }

    @Override
    public void onOpen(Connection connection) {
        sockets.put(connection.hashCode(), this);
        _connection = connection;
        handler.onJoin(connection.hashCode(), channel);
    }
}
}

的web.xml

<!-- Servlets -->
<servlet>
  <servlet-name>wsservlet</servlet-name>
  <servlet-class>com.mostka.server.WsServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>wsservlet</servlet-name>
  <url-pattern>/socket/*</url-pattern>
</servlet-mapping>

start.xml

etc/jetty-jmx.xml
etc/jetty.xml
etc/jetty-ajp.xml
etc/jetty-hightide.xml
# etc/jetty-ssl.xml
# etc/jetty-requestlog.xml
etc/jetty-deploy.xml
#etc/jetty-overlay.xml
etc/jetty-webapps.xml
etc/jetty-contexts.xml
etc/jetty-testrealm.xml
etc/jetty-jaas.xml

的jetty.xml

    <Configure id="Server" class="org.eclipse.jetty.server.Server">

        <!-- =========================================================== -->
        <!-- Server Thread Pool                                          -->
        <!-- =========================================================== -->
        <Set name="ThreadPool">
          <!-- Default queued blocking threadpool -->
          <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
            <Set name="minThreads">10</Set>
            <Set name="maxThreads">200</Set>
            <Set name="detailedDump">false</Set>
          </New>
        </Set>

        <!-- =========================================================== -->
        <!-- Set connectors                                              -->
        <!-- =========================================================== -->

        <Call name="addConnector">
          <Arg>
              <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
                <Set name="host"><Property name="jetty.host" /></Set>
                <Set name="port"><Property name="jetty.port" default="9627"/></Set>
                <Set name="maxIdleTime">300000</Set>
                <Set name="Acceptors">2</Set>
                <Set name="statsOn">false</Set>
                <Set name="confidentialPort">9626</Set>
            <Set name="lowResourcesConnections">20000</Set>
            <Set name="lowResourcesMaxIdleTime">5000</Set>
              </New>
          </Arg>
        </Call>

        <!-- =========================================================== -->
        <!-- Set handler Collection Structure                            -->
        <!-- =========================================================== -->
        <Set name="handler">
          <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
            <Set name="handlers">
             <Array type="org.eclipse.jetty.server.Handler">
               <Item>
                 <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
               </Item>
               <Item>
                 <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
               </Item>
             </Array>
            </Set>
          </New>
        </Set>

        <!-- =========================================================== -->
        <!-- extra options                                               -->
        <!-- =========================================================== -->
        <Set name="stopAtShutdown">true</Set>
        <Set name="sendServerVersion">true</Set>
        <Set name="sendDateHeader">true</Set>
        <Set name="gracefulShutdown">1000</Set>
        <Set name="dumpAfterStart">false</Set>
        <Set name="dumpBeforeStop">false</Set>

    </Configure>

错误:

java.lang.IllegalStateException: Websockets not supported on blocking connectors
    at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:214)
    at org.eclipse.jetty.websocket.WebSocketFactory.acceptWebSocket(WebSocketFactory.java:351)
    at org.eclipse.jetty.websocket.WebSocketServlet.service(WebSocketServlet.java:104)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:648)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:455)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)

完整错误堆栈http://sharetext.org/xr5i

客户端发送标题

请求

URL:ws://gwtver.jvmhost.net/socket/testChannel/a?key=123
Request Headersview source
Cache-Control:no-cache
Connection:Upgrade
Host:gwtver.jvmhost.net
Origin:http://gwtver.jvmhost.net
Pragma:no-cache
Sec-WebSocket-Extensions:x-webkit-deflate-frame
Sec-WebSocket-Key:O0QbqSZsNjKvMfdcElXbNQ==
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Query String Parametersview sourceview URL encoded
key:123

由于

1 个答案:

答案 0 :(得分:0)

你是对的。 WebSocket不支持阻塞连接器。

这主要是由于协议的性质和开发的API。

现在从阻塞连接器切换到SelectChannel连接器是明智的,因为所有未来版本的Jetty都完全消除了阻塞连接器。

新协议(SPDY,WebSocket,HTTP / 2.0),新API(javax.websocket,Java EE 7)和更新的Servlet规范(异步I / O)的压力基本上消除了使用阻塞连接器的可能性