Grails 2.3.7 - Java 1.7
我在core java中看到了下面的例子,并作为一个演示,试图在Grails中实现相同的功能,我知道有一些插件围绕websockets,但我试图自己弄清楚:
控制器1
package chat
class TestController {
def index() { }
}
index.gsp
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main">
<g:set var="entityName" value="${message(code: 'admin.label', default: 'Admin')}" />
<title><g:message code="default.create.label" args="[entityName,BAH,BAH]" /></title>
</head>
<body>
<form>
<input id="textMessage" type="text">
<input type="button" value="send" onClick="sendMessage();">
</form>
<br>
<textarea id="messagesTextarea" rows="10" cols="50">
</textarea>
<script type="text/javascript">
var webSocket=new WebSocket("ws://localhost:8080/chat/testing");
var messagesTextarea=document.getElementById("messagesTextarea");
var textMessage=document.getElementById("textMessage");
webSocket.onopen=function(message) {processOpen(message);};
webSocket.onmessage=function(message) {processMessage(message);};
webSocket.onclose=function(message) {processClose(message);};
webSocket.onerror=function(message) {processError(message);};
function processOpen(message) {
messagesTextarea.value +=" Server Connect.... "+"n";
}
function processMessage(message) {
messagesTextarea.value +=" Receive from Server ===> "+ message.data +"n";
}
function sendMessage() {
if (textMssage.value!="close") {
webSocket.send(textMessage.value);
messagesTextarea.value +=" Send to Server ===> "+ textMessage.value +"n";
textMessage.value="";
}else {
websocket.close();
}
}
function processClose(message) {
webSocket.send("Client disconnected......");
messagesTextarea.value +="Server Disconnected... "+"n";
}
function processError(message) {
messagesTextarea.value +=" Error.... n";
}
</script>
</body>
</html>
控制器2:
package chat
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/testing")
class TestingController {
@OnOpen
public void handleOpen() {
System.out.println("Client is now connected.");
}
@OnMessage
public String handleMessage(String message) {
System.out.println("Client sent: " + message);
String replyMessage = "echo "+message;
System.out.println("Send to Client: " + replyMessage);
return replyMessage;
}
@OnClose
public void handeClose() {
System.out.println("Client is now disconnected.");
}
@OnError
public void handleError(Throwable t) {
t.printStackTrace();
}
}
当我运行app
时我在chrome中得到以下错误:
WebSocket connection to 'ws://localhost:8080/chat/testing' failed: Error during WebSocket handshake: Unexpected response code: 404 index:37
WebSocket is already in CLOSING or CLOSED state.
and in textArea
Error....
Server Disconnected...
在控制台我看到:
Client sent: null
Send to Client: echo null
最初我尝试这样控制:
package chat
class TestingController extends TestingEndpoint {
}
和src/java/chat
package chat;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/testing")
class TestingEndpoint {
@OnOpen
public void handleOpen() {
System.out.println("Client is now connected.");
}
@OnMessage
public String handleMessage(String message) {
System.out.println("Client sent: " + message);
String replyMessage = "echo "+message;
System.out.println("Send to Client: " + replyMessage);
return replyMessage;
}
@OnClose
public void handeClose() {
System.out.println("Client is now disconnected.");
}
@OnError
public void handleError(Throwable t) {
t.printStackTrace();
}
}
这个方法产生了相同的结果,除了在ggts控制台
中没有任何内容。想知道是否有人有javax。websocket在Grails中工作…
还行,还不错
:
- gsp: 中的几个拼写错误
index.gsp
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main">
<g:set var="entityName" value="${message(code: 'admin.label', default: 'Admin')}" />
<title><g:message code="default.create.label" args="[entityName,BAH,BAH]" /></title>
</head>
<body>
<form>
<input id="textMessage" type="text">
<input type="button" value="send" onClick="sendMessage();">
</form>
<br>
<textarea id="messagesTextarea" rows="10" cols="50">
</textarea>
<script type="text/javascript">
var webSocket=new WebSocket("ws://localhost:8080/chat/annotated");
var messagesTextarea=document.getElementById("messagesTextarea");
webSocket.onopen=function(message) {processOpen(message);};
webSocket.onmessage=function(message) {processMessage(message);};
webSocket.onclose=function(message) {processClose(message);};
webSocket.onerror=function(message) {processError(message);};
function processOpen(message) {
messagesTextarea.value +=" Server Connect.... "+"n";
}
function processMessage(message) {
messagesTextarea.value +=" Receive from Server ===> "+ message.data +"n";
}
function sendMessage() {
if (textMessage.value!="close") {
webSocket.send(textMessage.value);
messagesTextarea.value +=" Send to Server ===> "+ textMessage.value +"n";
textMessage.value="";
}else {
websocket.close();
}
}
function processClose(message) {
webSocket.send("Client disconnected......");
messagesTextarea.value +="Server Disconnected... "+"n";
}
function processError(message) {
messagesTextarea.value +=" Error.... n";
}
</script>
</body>
</html>
现在结束点的实际修复,我从这里偶然发现它:https://tyrus.java.net/documentation/1.7/index/deployment.html例3.2。使用ServerContainer部署带注释的端点
所以修复是添加src/java/myservletcontextlistenerannotatedjava
package chat;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.websocket.DeploymentException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;
@WebListener
@ServerEndpoint("/annotated")
public class MyServletContextListenerAnnotated implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
final ServerContainer serverContainer = (ServerContainer) servletContextEvent.getServletContext()
.getAttribute("javax.websocket.server.ServerContainer");
try {
serverContainer.addEndpoint(MyServletContextListenerAnnotated.class);
} catch (DeploymentException e) {
e.printStackTrace();
}
}
/* @OnMessage
public String onMessage(String message) {
return message;
}
*/
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
@OnOpen
public void handleOpen() {
System.out.println("Client is now connected.");
}
@OnMessage
public String handleMessage(String message) {
System.out.println("Client sent: " + message);
String replyMessage = "echo "+message;
System.out.println("Send to Client: " + replyMessage);
return replyMessage;
}
@OnClose
public void handeClose() {
System.out.println("Client is now disconnected.");
}
@OnError
public void handleError(Throwable t) {
t.printStackTrace();
}
}
由于gsp中的端点已经更新为使用新端点,因此最后的操作是添加_Events。Groovy到脚本:
import groovy.xml.StreamingMarkupBuilder
eventWebXmlEnd = {String tmpfile ->
def root = new XmlSlurper().parse(webXmlFile)
root.appendNode {
'listener' {
'listener-class' (
'chat.MyServletContextListenerAnnotated'
)
}
}
webXmlFile.text = new StreamingMarkupBuilder().bind {
mkp.declareNamespace(
"": "http://java.sun.com/xml/ns/javaee")
mkp.yield(root)
}
}