First, define the Message format as follows:
Request: # message {type = "get", subject = "clientinfo", content = "all "}
Response: # message {type = "result", subject = "clientinfo", content = [# clientinfo, # clientinfo,...]}
Modify the client's request message:
clientthread. sendmsg (New message ("get", "client", "", "clientinfo", "all");
modify the server, add a method for obtaining all online users to chat_room: getmembers (Message)-> <br/> gen_server: Call (? Module, {get_member, message}) <br/>.
in the routing module. type and message. subject route request information to the above method
<Textarea style = "width: 1028px; Height: 530px;" readonly name = "code" class = "Java"> routemessage (type, sub, message) -> <br/> case type of <br/> "MSG"-> <br/> case sub of <br/> "chat"-> <br/> IO: format ("message_router: route to chat_room: Broadcast :~ P ~ N ", [Message]), <br/> chat_room: broadcastmsg (Message); <br/> _ Els-> <br/> IO: Format (" unkonw msssage subject: ~ P ~ N ", [sub]) <br/> end; <br/> "set"-> <br/> case sub of <br/> "clientinfo"-> <br/> chat_room: setuserinfo (Message ); <br/> _ Els-> <br/> IO: Format ("unkonw msssage subject :~ P ~ N ", [sub]) <br/> end; <br/> "get"-> <br/> case sub of <br/> "clientinfo"-> <br/> chat_room: getmembers (Message ); <br/> _ Els-> <br/> IO: Format ("unkonw msssage subject :~ P ~ N ", [sub]) <br/> end; <br/> _ Els-> <br/> {error, "Wrong message type" }< br/> end <br/>. </textarea>Call get_member in chat_room. Define a local method in getclient to use client_manager to obtain online users in the format of # clientinfo.
Chat_room.erl:
Handle_call ({get_member, MSG}, from, state)-> <br/> # message {content = content} = MSG, <br/> case binary_to_list (content) of <br/> "all"-> <br/> List = getclient ([], []), <br/> # message {from = ID} = MSG, <br/> thefrom = client_manager: getnick (ID), <br/> message = MSG # message {type = "result", from = thefrom, subject = "clientinfo ", content = List },< br/> {pid, _} = from, <br/> PID! {Get_member, message };< br/> _ Els-> <br/> OK <br/> end, <br/> {reply, OK, state} <br/>; <br/> getclient (Key, ulist)-> <br/> case client_manager: getnextclient (key) of <br/> [Record]-> <br/> next = record # clientinfo. ID, <br/> IO: Format ("record is :~ P ~ N ", [Record]), <br/> JSON = util_setinfoparas: deparaelement (record), <br/> IO: Format (" clientsession found :~ P ~ N ", [Record]), <br/> newulist = [JSON | ulist], <br/> getclient ([next], newulist ); <br/> []-> <br/> ulist <br/> end <br/>. </P> <p>
To facilitate subsequent parsing, the returned customer information must be pre-encoded in the format of jsonstring decode under Erlang. Therefore, the deparaelement/1 method is defined in util_setinfoparas.erl as needed.
Deparaelement (record)-> <br/> # clientinfo {Nick = Nick, <br/> sex = sex, <br/> age = age, <br/> province = province, <br/> city = city, <br/> posx = px, <br/> posy = py} = record, <br/> {OBJ, [<br/> {"Nick", list_to_binary (setdef (Nick, "S") },< br/> {"sex ", setdef (sex, "I") },< br/> {"Age", setdef (age, "I") },< br/> {"Province ", list_to_binary (setdef (Province, "S") },< br/> {"city", list_to_binary (setdef (city, "S "))}, <br/> {"posx", setdef (PX, "I") },< br/> {"posy", setdef (PY, "I ")} <br/>]} <br/>. </P> <p> setdef (Val, type)-> <br/> defv = case type of <br/> "S"-> <br/> ""; <br/> "I"-> <br/> 0; <br/> "L"-> <br/> [] <br/> end, </P> <p> case Val of <br/> undefined-> <br/> defv; <br/> Els-> <br/> Val <br/> end <br/>. <br/>After chat_room is processed, the result is packaged into a message and sent to the corresponding client process. The client process is then sent to the final client.
Handle_info ({get_member, message}, state)-> <br/> IO: Format ("client_session-getmember result ~ P ~ N ", [Message]), <br/> sendmsg (message, State), <br/> {noreply, State} <br/>;
Modify the client JavaCodeTo convert the received jsonstring to the bean object. Here, a special class getuserinfo is created to indicate the received result information.
Package COM. kinglong. socket. data; </P> <p> Import Java. util. arraylist; <br/> Import Java. util. date; </P> <p> Import net. SF. JSON. jsonarray; <br/> Import net. SF. JSON. jsonobject; </P> <p> public class getuserinfo extends packet {</P> <p> arraylist <clientinfo> content = NULL; </P> <p> Public getuserinfo () {<br/> This. JSON = new jsonobject (); <br/> settype ("get"); <br/> setsubject ("clientinfo"); <br/> setcreationdate (new date () ); <Br/>}</P> <p> Public getuserinfo (arraylist <clientinfo> List) {<br/> This. JSON = new jsonobject (); <br/> settype ("get"); <br/> setsubject ("clientinfo "); <br/> setcreationdate (new date (); <br/> setcontent (list ); <br/>}</P> <p> Public arraylist <clientinfo> getcontent () {<br/> jsonarray array = JSON. getjsonarray ("content"); </P> <p> arraylist <clientinfo> Infos = new arraylist <clientinfo> (); <br/> int size = array. si Ze (); <br/> for (INT I = 0; I <size; I ++) {<br/> jsonobject OBJ = array. getjsonobject (I); <br/> Infos. add (clientinfo) jsonobject. tobean (OBJ, clientinfo. class); <br/>}</P> <p> If (array = NULL) {<br/> return NULL; <br/>}< br/> else {<br/> If (content! = NULL) {<br/> return content; <br/>}< br/> else {<br/> content = Infos; <br/> return content; <br/>}</P> <p> Public void setcontent (arraylist <clientinfo> clients) {<br/> If (clients! = NULL) {<br/> This. content = clients; <br/>}< br/> This. JSON. put ("content", clients); <br/>}< br/>Modify the code of the client to parse the corresponding message type.
Public void run () {<br/> // todo auto-generated method stub <br/> inputstreamreader reader = new inputstreamreader (insT ); <br/> bufferedreader bfreader = new bufferedreader (Reader); <br/> while (isrunning) {<br/> string STR = NULL; <br/> try {<br/> byte [] DATA = new byte [1024]; <br/> int Len = 0; <br/> while (LEN = Inst. read (data)> 0) {<br/> STR = new string (data ). trim (); <br/> iterator <jsonobject> it = jsonparaser. getstring (STR); <br/> while (it. hasnext () {<br/> jsonobject OBJ = it. next (); <br/> If ("MSG ". equals (obj. get ("type") {<br/> message MSG = (Message) jsonobject. tobean (OBJ, message. class); <br/> MF. recmsg (MSG); <br/>}< br/> else if ("result ". equals (obj. get ("type") & "clientinfo ". equals (obj. get ("subject") {</P> <p> Map <string, class> mapclass = new hashmap <string, class> (); <br/> mapclass. put ("content", clientinfo. class); <br/> getuserinfo info = (getuserinfo) jsonobject. tobean (OBJ, getuserinfo. class, mapclass); <br/> iterator <clientinfo> clients = info. getcontent (). iterator (); <br/> while (clients. hasnext () {<br/> clientinfo in = clients. next (); <br/> MF. recmsg ("there are client NICK:" + in. getnick (); <br/>}< br/>} catch (ioexception E) {<br/> // todo auto-generated Catch Block <br/> system. out. println ("recmsg error" + E. getmessage (); <br/> isrunning = false; <br/>}< br/> try {<br/> thread. sleep (500); <br/>} catch (interruptedexception e) {<br/> // todo auto-generated Catch Block <br/> E. printstacktrace (); <br/>}< br/>}
The test results are as follows:
Start a client and change its nickname to clienta.
Start another client and change the nickname to clientb.
The clientb client obtains the current online user (only the nickname is printed here)