整个聊天室由两个界面组成,第一个界面用来注册用户的昵称。提交后,显示聊天页面,用户可以开始聊天。界面上部显示聊天信息。用户可以在界面底部输入消息,输入消息后回车提交。
首先建立一个领域模型用来保存聊天消息。
package com.tutorial
class Message {
String nickname
Date date = new Date()
String message
static constraints = {
}
}
系统加载完成后,会将所有历史消息全部加载到聊天界面。
在控制器中增加注册页面转发控制器和注册信息提交控制器
package com.tutorial
class ChatController {
def index() { }
def join(String nickname) {
if ( nickname.trim() == '' ) {
redirect(action:'index')
} else {
session.nickname = nickname
render (view: 'chat')
}
}
}
index.gsp
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main"/>
<title>Simple Chat</title>
</head>
<body>
<g:form action="join">
<label for="nickname">Please enter your name</label>
<g:textField name="nickname"/>
<g:submitButton name="Join Chat"/>
</g:form>
</body>
</html>
index页面中的form表单提交给join方法,join方法将提交过来的nickname保存到session,并将页面跳转到chat视图
chat中有两个功能,一个是显示所有聊天记录,一个是提交聊天消息
package com.tutorial
class ChatController {
......
def retrieveLatestMessages() {
def messages = Message.listOrderByDate(order: 'desc', max:10)
[messages:messages.reverse()]
}
def submitMessage(String message) {
new Message(nickname: session.nickname, message:message).save()
render "<script>retrieveLatestMessages()</script>"
}
}
chat.gsp
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main"/>
<title>Simple Chat</title>
<g:javascript library="jquery"/>
</head>
<body>
<div id="chatMessages"></div>
<input type="text" id="messageBox" name="message" onkeypress="messageKeyPress(this,event);"/>
<div id="temp"></div>
<script>
function messageKeyPress(field,event) {
var theCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
var message = $('#messageBox').val();
if (theCode == 13){
<g:remoteFunction action="submitMessage" params="\'message=\'+message" update="temp"/>
$('#messageBox').val('');
return false;
} else {
return true;
}
}
function retrieveLatestMessages() {
<g:remoteFunction action="retrieveLatestMessages" update="chatMessages"/>
}
function pollMessages() {
retrieveLatestMessages();
setTimeout('pollMessages()', 5000);
}
pollMessages();
</script>
</body>
</html>
在chat.gsp代码中会不断的请求服务器端,并更新客户界面就是pollMessages()和retrieveLatestMessages()这两个方法的功能,而retrieveLatestMessages()方法更新的工作时调用了Grails内置的 标签,将retrieveLatestMessages页面显示出来。
retrieveLatestMessages.gsp
<g:each in="${messages}" var="message">
<div>
<span class="nickname">${message.nickname}</span> - <span class="msg">${message.message}</span>
</div>
</g:each>
retrieveLatestMessages控制器会将模型中最后10个实例拿出来提交给retrieveLatestMessages.gsp视图显示。
如果想修改系统启动时的默认访问页为聊天用户注册的页面,可以修改config/UrlMappings.groovy
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/" (controller:"chat", action:"index")
"500"(view:'/error')
}
}
上面只是一个非常简单的例子,有很多漏洞,这个例子只是想说明Grails简单易用的特性,这个实例的完整代码可以在这里下载。