zoukankan      html  css  js  c++  java
  • ICE:实现简单的聊天室

    目标:实现一个简单的聊天室。本文实现的聊天室仅出于演示ICE的多播功能,即由一个Client发送的消息,广播至注册的其他Client上。以后的系列文章,将逐步完善这个例子,使其成为一个现实意义上可用的聊天室软件。


    Slice定义:

    module ChatSpaceDef
    {
           //回调函数接口,就是客户端传递给服务器,服务器接收到的一个方法代理签名
           interface CallBack
           {
                  void GetInput(string content);
           };
           //在线列表
           dictionary<string,CallBack *> CacheMap;
           //聊天室功能列表
           interface ChatSpace
           {
                  bool Register(string name);//注册
                  void SetInput(string content);//发送消息
                  void Unregister();//退出
                  void SetupCallback(CallBack * cp);//设置回调
           };
    
    };
    
    运行命令:
    slice2cs --output-dir generated *.ice
    此命令将生成Client和Server都要使用的应用程序骨架ChatSpaceDef.cs文件。要了解该文件的类的所有信息,
    请参考Ice用户手册

    定义服务器端

    对服务器而言,实现ChatSpaceDisp_抽象基类即可,换言之,需要实现:
     bool Register(string name);//注册
     void SetInput(string content);//发送消息
     void Unregister();//退出
     void SetupCallback(CallBack * cp);//设置回调
    
    这4个方法。代码如下:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using ChatSpaceDef;
    
    namespace ChatSpace
    {
        public sealed class ChatSpaceI : ChatSpaceDisp_
        {
            public override bool Register(string name, Ice.Current current__)
            {
                Console.WriteLine("验证 {0} 是否被注册了!", name);
                return !m_cache_map.Contains(name);
            }
    
            public override void SetInput(string content, Ice.Current current__)
            {
           //向其他人广播消息
                string user_name = current__.ctx["user_name"];
    
                foreach (string key in m_cache_map.Keys)
                {
                    if (key == user_name)
                    {
                        continue;
                    }
                    m_cache_map[key].GetInput(content, current__.ctx);
                }
            }
    
            public override void Unregister(Ice.Current current__)
            {
                if (current__.ctx["user_name"] != null)
                {
                    m_cache_map.Remove(current__.ctx["user_name"]);
                    Console.WriteLine("注销{0}成功", current__.ctx["user_name"]);
                }           
           
                
            }
    
            public override void SetupCallback(CallBackPrx cp, Ice.Current current__)
            {           
                if (current__ != null && current__.ctx["user_name"] != null)
                {
                    string user_name = current__.ctx["user_name"];
                    Console.WriteLine("上下文是user_name={0}", user_name);
                    m_cache_map.Add(user_name, cp);
                }
                else
                {
                    throw new Exception("上下文错误!");
                }
    
              
            }
    
            CacheMap m_cache_map = new CacheMap();
    
        }
    }
    
    上述代码都非常简单易懂,需要解释的是:Ice.Current表示调用者携带的上下文信息,这是Ice的内部机制,你可以在
    方法调用上,通过Context对象携带其他与调用相关的信息,注意,它不是方法调用的参数,它是Client和Server在网络
    中网络环境下传递信息的一种载体。
    
    定义Server端配置config.server:
    Callback.Server.Endpoints=tcp -p 12345:udp -p 12345
    
    #
    # Warn about connection exceptions
    #
    Ice.Warn.Connections=1
    
    #
    # Network Tracing
    #
    # 0 = no network tracing
    # 1 = trace connection establishment and closure
    # 2 = like 1, but more detailed
    # 3 = like 2, but also trace data transfer
    #
    #Ice.Trace.Network=1
    
    #
    # Protocol Tracing
    #
    # 0 = no protocol tracing
    # 1 = trace protocol messages
    #
    #Ice.Trace.Protocol=1
    
    #
    # Security Tracing
    #
    # 0 = no security tracing
    # 1 = trace messages
    #
    #IceSSL.Trace.Security=1
    
    
    server端的主程序非常简单Server.cs:
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ChatSpace
    {
        public class Server : Ice.Application
        {
            public override int run(string[] args)
            {
                Ice.ObjectAdapter adapter = communicator().createObjectAdapter("Callback.Server");           
                adapter.add(new ChatSpaceI(), communicator().stringToIdentity("callback"));
                adapter.activate();
                communicator().waitForShutdown();
                return 0;
            }
    
            public static void Main(string[] args)
            {
                Server app = new Server();
                int status = app.main(args, "config.server");
                if (status != 0)
                {
                    System.Environment.Exit(status);
                }
            }
        }
    }
    
     
     

    定义客户端

    对客户端而言,只需要实现回调方法即可了CallBackI.cs。

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    using ChatSpaceDef;
    
    namespace Client
    {
        public sealed class CallBackI:CallBackDisp_
        {
            public override void GetInput(string content, Ice.Current current__)
            {
                System.Console.WriteLine("服务器传递过来的信息:{0} Say:{1}",current__.ctx["user_name"],content);
            }
        }
    }
    
    客户端主程序Client.cs:
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    using ChatSpaceDef;
    
    namespace Client
    {
        class Client : Ice.Application
        {
            static void Main(string[] args)
            {
                Client app = new Client();
                int status = app.main(args, "config.client");
                if (status != 0)
                {
                    System.Environment.Exit(status);
                }
            }
    
            public override int run(string[] args)
            {
                ChatSpacePrx spacePrx = ChatSpacePrxHelper.
                    checkedCast(communicator().propertyToProxy("Callback.CallbackServer"));
    
                if (spacePrx == null)
                {
                    System.Console.WriteLine("网络配置无效!");
                    return 1;
                }
                System.Console.WriteLine("请输入用户名:rn");
                string user_name = Console.ReadLine();
    
                if (spacePrx.Register(user_name) == false)
                {
                    System.Console.WriteLine("该用户名已被注册!");
                    return 1;
                }
                Ice.ObjectAdapter adapter = communicator().createObjectAdapter("Callback.Client");
                adapter.add(new CallBackI(), communicator().stringToIdentity("callbackReceiver"));
                adapter.activate();
                          
                
                CallBackPrx callbackPrx = CallBackPrxHelper.uncheckedCast(adapter.createProxy(communicator().stringToIdentity("callbackReceiver")));
                Ice.Context ctx = new Ice.Context();
                ctx.Add("user_name", user_name);
    
                spacePrx.SetupCallback(callbackPrx,ctx);
    
                System.Console.WriteLine("请输入聊天内容:rn");
                string content = "";
                while (content != "X")            
                {
                    content = System.Console.ReadLine();
                    spacePrx.SetInput(content,ctx);                
                }
                spacePrx.Unregister(ctx);
    
                return 0;
    
            }
        }
    }
    
    客户端配置文件:
    
    Callback.CallbackServer=callback:tcp -p 12345:udp -p 12345
    Callback.Client.Endpoints=tcp:udp
    
    #
    # Warn about connection exceptions
    #
    Ice.Warn.Connections=1
    
    #
    # Network Tracing
    #
    # 0 = no network tracing
    # 1 = trace connection establishment and closure
    # 2 = like 1, but more detailed
    # 3 = like 2, but also trace data transfer
    #
    #Ice.Trace.Network=1
    
    #
    # Protocol Tracing
    #
    # 0 = no protocol tracing
    # 1 = trace protocol messages
    #
    #Ice.Trace.Protocol=1
    
    #
    # Security Tracing
    #
    # 0 = no security tracing
    # 1 = trace messages
    #
    #IceSSL.Trace.Security=1
    
    
    至此,一个多播聊天室就此完成。
    
    编译运行:
    
     
     
    ICE,SQLite,JasperReport……开源技术讨论群:25935569,欢迎关注开源技术应用的朋友一起交流进步。
    项目下载:项目文件 ICEChatSpace
  • 相关阅读:
    List of all Oracle Server Parameters
    dbcc Trace
    站在巨人的肩膀上 书籍推荐 (zz)
    浅谈JS包装对象
    与 JavaScript 模块相关的所有知识点
    你真的懂Promise吗
    vue动态绑定class与style总结
    vue使用axios实现excel文件下载的实现
    CSRF 与 XSS
    推荐10个很棒的 JS 库
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318903.html
Copyright © 2011-2022 走看看