连接到 WebSocket 失败:意外响应代码:404

Connection to WebSocket Failed: unexpected response code : 404

我正在尝试与 javax.websocket 聊天。 我正在使用圣杯。 3.0

这是我的控制器

package chatting

import javax.websocket.server.ServerEndpoint;
import javax.websocket.OnMessage;

@ServerEndpoint("/echo")
public class WebsocketHomeController {

    def index() { }

    @OnMessage


    public String echo(String incomingMessage) {
            return "I got this (" + incomingMessage + ")"
            + " so I am sending it back !";
        }
    }

这是我的index.gsp

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    <title>Web Socket JavaScript Echo Client</title>
    <script language="javascript" type="text/javascript">
        var echo_websocket;
        function init() {
            output = document.getElementById("output");
        }
        function send_echo() {
            var wsUri = "ws://192.168.1.2:8080/WebsocketHome/echo";
            writeToScreen("Connecting to " + wsUri);
            echo_websocket = new WebSocket(wsUri);
            echo_websocket.onopen = function (evt) {
                writeToScreen("Connected !");
                doSend(textID.value);
            };
            echo_websocket.onmessage = function (evt) {
                writeToScreen("Received message: " + evt.data);
                echo_websocket.close();
            };
            echo_websocket.onerror = function (evt) {
                writeToScreen('<span style="color: red;">ERROR:</span> '
                + evt.data);
                echo_websocket.close();
            };
        }
        function showErrorInfo(e) {
            alert('Error connecting socket'+e);
        }

        function doSend(message) {
            echo_websocket.send(message);
            writeToScreen("Sent message: " + message);
        }
        function writeToScreen(message) {
            var pre = document.createElement("p");
            pre.style.wordWrap = "break-word";
            pre.innerHTML = message;
            output.appendChild(pre);
        }
        window.addEventListener("load", init, false);
    </script>
</head>
<body>
    <h1>Echo Server</h1>
    <div style="text-align: left;">
        <form action="">
            <input onclick="send_echo()" value="Press to send"
                   type="button">
            <input id="textID" name="message" value="Hello Web Sockets"
                   type="text">
            <br>
        </form>
    </div>
    <div id="output"></div>
</body>
</html>

这是结果..

我不知道..为什么我会收到这个错误...

我试过像这样调试我的代码..

public String echo(String incomingMessage) {
println "this is runing"
return "I got this (" + incomingMessage + ")"
+ " so I am sending it back !";
}

然后我在我的控制台日志中得到“这是 运行”

我必须做什么?

要在 grails 3 中添加侦听器:

  1. 将 doWithSpring 闭包添加到 ìnit/appName/Application.groovy

https://github.com/vahidhedayati/testwschatapp/blob/master/grails-app/init/testwschatapp/Application.groovy#L7-L11

Closure doWithSpring() {
    {->
        myChatConfig DefaultChatConfig
    }
}

在 grails-app/init/{appname}/DefaultChatConfig.groovy

中创建一个文件

https://github.com/vahidhedayati/testwschatapp/blob/master/grails-app/init/testwschatapp/DefaultWsChatConfig.groovy

package myappName

import path.to.WebsocketHomeController

import org.springframework.boot.context.embedded.ServletContextInitializer
import org.springframework.context.annotation.Bean

import javax.servlet.ServletContext
import javax.servlet.ServletException

class DefaultChatConfig {

    @Bean
    public ServletContextInitializer myInitializer() {
        return new ServletContextInitializer() {
            @Override
            public void onStartup(ServletContext servletContext) throws ServletException {
                ServletContext.addListener(WebsocketHomeController)
            }
        }
    }

}

您需要在第 2 个文件导入的顶部整理导入行 path.to.WebsocketHomeController

顺便说一句,在我对聊天插件的评论中,我建议您可以制作自己的界面。我的意思是与插件交互。如果插件为您完成了很多功能,但假设您希望管理自己的用户。

您可以在自己的应用程序中编写调用聊天 类 到 view/edit/delete 等的服务。与我展示如何将管理员帐户添加到聊天域的方式完全相同 类 通过文档中的 bootstrap。

其中一些东西需要数年才能完全理解,但如果我想偷懒,我可以将这些域 类 从聊天插件复制到测试项目,然后使用 grails 获取它来生成控制器和他们的视图然后返回主项目并复制新的 controllers/views。

如果插件提供功能 services/domain 类 / 控制器。它们都可以在您的主应用程序中本地重用。您可以扩展,或者如果它很好,则将其贡献回插件本身供其他人使用