GWT,(简单)Websockets和405警告

时间:2014-03-24 14:03:51

标签: javascript gwt websocket

我无法使用GWT(2.6.0)运行基本的WebSocket功能。

我正在使用默认生成的GWT应用程序和GWT的内置服务器,只是尝试扩展代码以允许WebSocket通信。当试图打开/“升级”连接时,我看到405警告。

来源如下。当我尝试连接时(单击“连接”按钮),警告将出现在Eclipse控制台中。发送消息并尝试关闭连接此时不执行任何操作。

1:控制台消息:

[WARN] 405 - GET /jtreeservertest/echo (127.0.0.1) 1455 bytes   Request headers  
      Upgrade: websocket  
      Connection: Upgrade  
      Host: 127.0.0.1:8888  
      Origin: http://127.0.0.1:8888  
      Pragma: no-cache  
      Cache-Control: no-cache  
      Sec-WebSocket-Key: GdLkR0qCKcRD6fvjafKNCg==  
      Sec-WebSocket-Version: 13  
      Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame  
      User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154   Safari/537.36    Response headers  
      Content-Type: text/html;charset=ISO-8859-1  
      Cache-Control: must-revalidate,no-cache,no-store  
      Content-Length: 1455

2:EchoEndpoint.java:

import java.io.IOException;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

@ServerEndpoint("/echo") public class EchoEndpoint extends RemoteServiceServlet {

    @OnOpen public void openConnection(Session session) {
        System.out.println("Connection opened: " + session);
    }

    @OnError public void onError() {
        System.out.println("error");
    }

    @OnMessage
   public void onMessage(Session session, String msg) {
      try {
         session.getBasicRemote().sendText(msg);
        } catch (IOException e) {
            System.out.println(e);
        }
   }
}

3:web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
         version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee">

  <!-- Servlets -->
  <servlet>
    <servlet-name>greetServlet</servlet-name>
    <servlet-class>jTreeServerTest.server.GreetingServiceImpl</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>greetServlet</servlet-name>
    <url-pattern>/jtreeservertest/greet</url-pattern>
  </servlet-mapping>

  <servlet>
     <servlet-name>ChatServlet</servlet-name>
     <servlet-class>jTreeServerTest.server.EchoEndpoint</servlet-class>
  </servlet>

    <servlet-mapping>
        <servlet-name>ChatServlet</servlet-name>
        <url-pattern>/jtreeservertest/echo</url-pattern>
    </servlet-mapping>

  <!-- Default page to serve -->
  <welcome-file-list>
    <welcome-file>JTreeServerTest.html</welcome-file>
  </welcome-file-list>

</web-app>

4:index.html:

    <script type="text/javascript" language="javascript" src="jtreeservertest/jtreeservertest.nocache.js"></script>

        <script>
            var ws = null;
            function connect() {
                ws = new WebSocket("ws://127.0.0.1:8888/jtreeservertest/echo");
                ws.onopen = function(){
                    document.getElementById("chatlog").textContent = "connected\n";
                };
                ws.onmessage = function(message){
                    document.getElementById("chatlog").textContent += message.data + "\n";
                };
                ws.onclose = function(){
                       console.log('Connection closed');
                    }
                ws.onerror = function(error){
                       console.log('Error detected: ' + error);
                    }
            }
            function postToServer(){
                ws.send(document.getElementById("msg").value);
                document.getElementById("msg").value = "";
            }
            function closeConnect(){
                ws.close();
            }
        </script>
...
       <textarea id="chatlog" readonly></textarea><br/>
        <input id="msg" type="text" />
        <button type="submit" id="sendButton" onClick="postToServer()">Send!</button>
        <button type="submit" id="sendButton" onClick="closeConnect()">End</button>
<button type="submit" id="connectButton" onClick="connect()">Connect</button>

1 个答案:

答案 0 :(得分:1)

首先,DevMode的嵌入式服务器不支持javax.websocket

但即使您将webapp部署到支持它的servlet容器,它仍然会因同样的 405 Method Not Allowed 错误而失败。

这是因为您extends RemoteServiceServlet(没有明显原因)只接受POST次请求,而您的浏览器只有GET Upgrade: websocket次请求。

您应该扩展javax.websocket.server.Endpoint或者只扩展 no 并拥有@ServerEndpoint注释。

但即使这样也不够:您的webapp将不再启动,因为端点不是servlet,并且您在web.xml中的<servlet>中声明了它。您应该依赖类路径扫描,或者从ServletContextListener部署websocket端点;见https://tyrus.java.net/documentation/latest/index/deployment.html