0

我做了 websocket 服务器。它在本地主机上工作,但是当我将它部署到服务器时,我得到了错误。我找不到解决方案。在本地主机上,我使用为码头 8.1.7 嵌入的 gwt 服务器。在部署服务器上有太多码头 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>

开始.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

码头.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

谢谢

4

1 回答 1

0

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

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

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

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

于 2013-07-08T14:07:08.187 回答