Erlang 聊天室程序(六) 设置客户端程序2

           上篇开了个头编写了基本的框架,这次连同客户端服务器端代码一起完善下。

           首先修改客户端代码:

           之前在数据交换部分,客户端中定义了一个Message bean类,里面包含了发送一条消息所需要的基本信息,包括id、type、subject、from、to、content等。但这里的

content是一个String 类型,如果要表示更复杂的消息就不太适用了。

           由于所有的消息id、type、subject、from、to 这几个成员的类型是确定的,对应的操作方法也是固定的,所以我们抽象出一个抽象类:Packet 用来表示交互中的所有消息:

Packet.java:

       与之前不同的是这次将Bean解析为JSON String的任务交给Bean本身。可以看到以上代码中并没有定义content的实现,所以具体的消息可根据自身需要来定制。

       根据这个思想,改造普通消息类Message:              再修改下发送部分的代码,直接调用对象的toString()方法:


         新建一个类ClientInfo 表示客户端要设置的信息:


             新建设置客户端消息类:SetClientInfo继承Packet类


           可以看到这里将content 设置为了刚才的ClientInfo 对象。

           下面修改服务器端:

           先要去掉JSON数据解析时的is_binary判断,因为以后发送的消息content里不一定就是binary了。


            再修改client_manager.erl 中更改客户端信息部分的代码,将content中的json数据转成#clientinfo,再更新到数据表中去。

            为此新建一个专门的模块util_SetInfoParas.erl处理setClientInfo消息:


           接着在更新数据库前调用以上代码:

           client_manager.erl:

              更新成功后,会将此消息广播给所有的在线用户:

chat_room.erl


      最后需要修改util_MessageParas.erl中的JSON编码部分,判断如果要发送给客户端的Message消息内容是list的话才转成相应的字符串。


        再修改客户端收到消息后的解析代码:


           测试结果如下:



        另外,既然能够设置客户端的昵称了,那么就再实现下发消息时from的替换吧:

先为client_manager添加获取客户端昵称功能,获取不到或undfined就取默认的:

复制代码
getNick(Key)->
    case ets:lookup(clientinfo, Key) of
        [Record]->
            #clientinfo{nick=Nick}=Record,
            case Nick of
                undefined ->
                    "client"++integer_to_list(Key);
                Nick->
                     Nick
            end;
        []->
            "client"++integer_to_list(Key)
    end
.
复制代码

   再修改设置个人信息后的通知消息:

复制代码
handle_call({set_clientinfo,Message},From,State)->
    %we can send result message to client
    %or send a broadcast message to all client 
    #message{from=Id}=Message,
    [Client]=client_manager:getClient(Id),
    #clientinfo{pid=Pid}=Client,
    TheNick=client_manager:getNick(Id),    
    case client_manager:updateClient(Message)of
        {ok,Rec}->            
            #clientinfo{nick=Nick}=Rec,            
            %Content=["client",integer_to_list(Id),"has change nickname:"|Nick],
            %[Cont]=["client"|integer_to_list(Id)],
            %io:format("Cont is:~p~n",[Cont]),
            %[Cont1]=[Cont|"has change nickname:"],
            %io:format("Cont1 is:~p~n",[Cont1]),
            %[Content]=[Cont1|Nick],
            %io:format("Content is:~p~n",[Content]),
            
            Pid!{setinfo,Rec},                    
            {Content}={TheNick ++ " has change nickname:" ++ Nick},
               NewMessage=#message{id="0",
                             from=Id,
                             to="",
                             content=Content,
                             type="msg",
                             subject="chat",
                             time=Message#message.time},
            io:format("Notice Message is:~p~n",[NewMessage]),
            sendMsg(NewMessage,[]);
        {false,Rec}->
            ok
    end,
    {reply,ok,State}
.
复制代码

 

    在修改client_session中下发时的from:

复制代码
handle_info({dwmsg,Message},State)->
    %here we should set from back
    io:format("client_session dwmsg state is ~p~n",[State]),
    #message{from=Id}=Message,
    Nick=client_manager:getNick(Id),    
    NewMessage =Message#message{from=Nick},
    JSON=util_MessageParas:paraseEncode(NewMessage),
    io:format("client_session dwmsg recived ~p~n",[JSON]),
    case gen_tcp:send(State#clientinfo.socket, JSON)of
        ok->
            io:format("client_session dwmsg sended ~n");
        {error,Reason}->    
            io:format("client_session dwmsg sended error ~p ~n",Reason)
    end,
    {noreply,State};
复制代码

测试效果如下:

 

 

 

 

 

 

 

 

 

posted on   心笑峰  阅读(534)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述

导航

< 2012年3月 >
26 27 28 29 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
1 2 3 4 5 6 7
点击右上角即可分享
微信分享提示