霸哥的blog中提到过Erlang服务器在通信中与客户端的数据交换方式:yufeng
为了简单起见这个聊天室程序采用json,要使用到rfc4627这个库
先定义一个Message类:
public class Message {
String id; //消息ID
String type; //消息类型
String from; //发送方
String to; //接收方
String subject; //主题
String content; //内容
Date creationDate; //时间
public Message(String type,String from,String to,String subject,String content){
this.id =MessageIdGenerator.nextId();
this.type=type;
this.from=from;
this.to=to;
this.subject=subject;
this.content=content;
this.creationDate=new Date();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
}
再定义一个JSON的工具类:
public class JSONParaser {
public static JSONObject getJSON(Object content){
try{
JSONObject result = JSONObject.fromObject(content);
return result;
}
catch(Exception ex){
return null;
}
}
public static Object getString(String json){
try{
JSONObject jobj=JSONObject.fromObject(json);
return JSONObject.toBean(jobj);
}
catch(Exception ex){
return null;
}
}
}
再修改SOCKET 发送部分代码:
public void sendMsg(Message msg){
try {
String data=(JSONParaser.getJSON(msg)).toString();
oust.write(data.getBytes());
oust.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
测试下发送后服务器端接收到的数据:
client_session dwmsg recived {message,undefined,msg,
[6],
undefined,undefined,
<<"{\"content\":\"aaaaa\",\"creationDate\":{\"date\":27,\"day\":1,\"hours\":13,\"minutes\":10,\"month\":1,\"seconds\":26,\"time\":1330319426281,\"timezoneOffset\":-480,\"year\":112},\"from\":\"client1\",\"id\":\"x8yL-2\",\"subject\":\"chat\",\"to\":\"\",\"type\":\"msg\"}">>,
undefined}
client_session dwmsg sended
服务器端新建一个模块util_MessageParas,将收到的json数据转成内部可识的message:
%% Author: Administrator
%% Created: 2012-2-27
%% Description: TODO: Add description to util_MessageParas
-module(util_MessageParas).
%%
%% Include files
%%
%%-include("json.hrl").
-include("message.hrl").
%%
%% Exported Functions
%%<<"{\"content\":\"aaa\",\"creationDate\":{\"date\":27,\"day\":1,\"hours\":18,\"minutes\":8,\"month\":1,\"seconds\":26,\"time\":1330337306984,\"timezoneOffset\":-480,\"year\":112},\"from\":\"client1\",\"id\":\"289n-2\",\"subject\":\"chat\",\"to\":\"\",\"type\":\"msg\"}">>
-export([paraseDecode/1]).
%%
%% API Functions
%%
%%
%% Local Functions
%%
%paras json data to message
paraseDecode(Bin)->
case rfc4627:decode(Bin) of
{ok,Obj,_Re}->
paraElements(Obj);
{error,Reason}->
{error,Reason}
end
.
%we get elements from decoded json,
%it has to be 7 elements
paraElements(Obj)->
{obj,List}=Obj,
Data =#message{},
%catch exception here
try paraEle(List,Data)
catch
{error,Reason,NewData}->
io:format("Format"),
{error,Reason,NewData}
end
.
paraEle([Ele|Els],Data)->
NewData=para(Ele,Data),
paraEle(Els,NewData)
;
paraEle([],Data)->
Data
.
%length of content should not more than 1000
para({"content",Val},Data) when is_binary(Val)->
io:format("para content:~p~n",[Data]),
Content=binary_to_list(Val),
if length(Content)<1000 ->
NewData=Data#message{content=Content},
io:format("paraed content:~p~n",[NewData]),
NewData;
true ->
throw({error,"illegal Content value",Data})
end
;
para({"to",Val},Data) when is_binary(Val)->
io:format("para to:~p~n",[Data]),
To =binary_to_list(Val),
NewData=Data#message{to=To}
;
para({"id",Val},Data) when is_binary(Val)->
io:format("para id:~p~n",[Data]),
Id=binary_to_list(Val),
NewData=Data#message{id=Id}
;
para({"subject",Val},Data) when is_binary(Val)->
io:format("para subject:~p~n",[Data]),
Sub=binary_to_list(Val),
%we should validate subject here
if Sub=:="chat" ->
NewData=Data#message{subject=Sub};
true ->
%throw exception
throw({error,"illegal subject value",Data})
end
;
para({"type",Val},Data) when is_binary(Val)->
io:format("para type:~p~n",[Data]),
Type = binary_to_list(Val),
if Type=:="msg"->
NewData=Data#message{type=Type};
true ->
%throw exception
throw({error,"illegal type value",Data})
end
;
para({"from",Val},Data) when is_binary(Val)->
io:format("para from:~p~n",[Data]),
From=binary_to_list(Val),
NewData=Data#message{from=From}
;
para({"creationDate",Val},Data)->
Data
;
para({Key,Val},Data)->
%no mache
%throw exception
throw({error,"unkown element",Data})
.
paraseEncode()->
ok
.
做下测试:
util_MessageParas:paraseDecode(<<"{\"content\":\"aaa\",\"creationDate\":{\"date\":27,\"day\":1,\"hours\":18,\"minutes\":8,\"month\":1,\"seconds\":26,\"time\":1330337306984,\"timezoneOffset\":-480,\"year\":112},\"from\":\"client1\",\"id\":\"289n-2\",\"subject\":\"chat\",\"to\":\"\",\"type\":\"msg\"}">>).
para content:{message,undefined,undefined,undefined,undefined,undefined,
undefined,undefined}
paraed content:{message,undefined,undefined,undefined,undefined,undefined,
"aaa",undefined}
para from:{message,undefined,undefined,undefined,undefined,undefined,"aaa",
undefined}
para id:{message,undefined,undefined,"client1",undefined,undefined,"aaa",
undefined}
para subject:{message,"289n-2",undefined,"client1",undefined,undefined,"aaa",
undefined}
para to:{message,"289n-2",undefined,"client1",undefined,"chat","aaa",
undefined}
para type:{message,"289n-2",undefined,"client1",[],"chat","aaa",undefined}
{message,"289n-2","msg","client1",[],"chat","aaa",undefined}
OK,收到的数据可以正常地解析为message了。
注:
在此处只需要将json数据的外层转换为message消息。message消息针对不同的类型和作用会有不同的json内容,所以内层数据应该在具体的消息处理部分再调用相应的paras处理。