Archived

This forum has been archived. Please start a new discussion on GitHub.

Chat Demo SessionCallbackAdapter problem

Hello! I'm trying to implement Chat Demo server in c#. I implemented ChatRoom like this:
    using Chat.Server.PullModel;

    public class ChatRoom
    {
        private static Object syncobject = new System.Object();

        private Dictionary<String, ChatRoomCallbackAdapter> members;
        private HashSet<String> reserved;        
        private Boolean trace;
        private Ice.Logger logger;

        #region [utilities]
        private void Init()
        {
            this.reserved = new HashSet<String>();
            this.members = new Dictionary<String, ChatRoomCallbackAdapter>();
        } 
        #endregion

        #region [ctor]
	public ChatRoom(Boolean trace, Ice.Logger logger)
        {
            this.Init();
            this.trace  = trace;
            this.logger = logger;
        } 
	#endregion

        public void Reserve(String name)
        {
            lock(syncobject)
            {
                if(this.members.ContainsKey(name) || this.reserved.Contains(name))
                {
                    throw new Exception("user already exists");
                }
                this.reserved.Add(name);
            }
        }
        public void UnReserve(String name) 
        {
            lock(syncobject)
            {
                this.reserved.Remove(name);
            }
        }
        public void Join(String name, ChatRoomCallbackAdapter callback)
        {
            lock(syncobject)
            {                
                this.reserved.Remove(name);

                var names = new List<String>();
                foreach(var item in this.members)
                {
                    names.Add(item.Key);
                }

                callback.Init(names);
                this.members[name] = callback;

                var e = new UserJoinedEvent(DateTime.Now.ToBinary(), name);
                foreach(var item in this.members)
                {
                    item.Value.Join(e);
                }

                if(this.trace)
                {
                    this.logger.trace("info", name + " user joined");
                }
            }
        }
        public void Leave(String name)
        {
            lock(syncobject)
            {
                this.members.Remove(name);

                var e = new UserLeftEvent(DateTime.Now.ToBinary(), name);
                foreach(var item in this.members)
                {
                    item.Value.Leave(e);
                }

                if(this.trace)
                {
                    this.logger.trace("info", name + " user left");
                }
            }
        }
        public Int64 Send(String name, String message)
        {
            lock(syncobject)
            {
                var ts = DateTime.Now.ToBinary();
                var e  = new MessageEvent(ts, name, message);
                foreach(var item in this.members)
                {
                    item.Value.Send(e);
                }

                if(this.trace)
                {
                    this.logger.trace("info", "user '" + name + "' sent message");
                }
                return ts;
            }
        }
    }

Am I right writing like that?

Class ChatRoomCallbackAdapter I wrote like this:
    public abstract class ChatRoomCallbackAdapter
    {
        public abstract void Init(List<String> names);
        public abstract void Join(Chat.Server.PullModel.UserJoinedEvent e);
        public abstract void Leave(Chat.Server.PullModel.UserLeftEvent e);
        public abstract void Send(Chat.Server.PullModel.MessageEvent e);
    }

Then I wrote next:
    using Chat.Server.PushModel;
    /// <summary>
    /// Push model session callback adapter
    /// </summary>
    public class SessionCallbackAdapter : ChatRoomCallbackAdapter
    {
        #region [ctor]
        public SessionCallbackAdapter
            (
                ChatRoomCallbackPrx cbproxy, 
                ChatSessionPrx ssproxy,
                Boolean trace,
                Ice.Logger logger,
                String name
            )
        {
        }
        #endregion

        #region [ChatRoomCallbackAdapter implementation]
        public override void Init(List<String> names)
        {
            Callback_ChatRoomCallback_Init InitCb = // method??;
        }
        public override void Join(Chat.Server.PullModel.UserJoinedEvent e)
        {
            throw new NotImplementedException();
        }
        public override void Leave(Chat.Server.PullModel.UserLeftEvent e)
        {
            throw new NotImplementedException();
        }
        public override void Send(Chat.Server.PullModel.MessageEvent e)
        {
            throw new NotImplementedException();
        } 
        #endregion        
    }

What method should I pass for each delegate? How do I set callbacks (Init, Join, Leave..)? In c#.
Also as I looked thru the tutorial there is no servants implementation at the phase I've stopped (i.e. SessionCallbackAdapter implementation) is that normal, or I have missed something?
Thanks!

Comments

  • xdm
    xdm La Coruña, Spain
    Hi Aleksey,

    The ChatRoom implementation you posted seems correct.

    ChatRoomCallbackAdapter can be just an interface, in C++ we use an abstract class because there isn't interfaces in C++.

    In your SessionCallbackAdapter implementation you should use C# AMI invocations, see Asynchronous Method Invocation (AMI). Is better to use the "Type-Safe Completion Callbacks" explained in the above link.

    The servants that are implemented in chat demo are the sessions, and session managers, the article explain both.

    Bests,
    Jose
  • Thanks! That was rather helpful!!! So as far as I understand I need to use the proxy wcich I do instantiate in the SessionCBAdapter class? I get it. Thanks one more time!
  • xdm
    xdm La Coruña, Spain
    Yes you need to call the corresponding cbproxy method, using the C# AMI API to avoid blocking.

    You will see when implement the session servant that cbproxy is the callback passed from the client as its callback proxy.
  • I'm writng this, but that's not working. I thought whenCompleted method should take its class calling callback..:confused:
       public void Init(List<String> names)
       {            
          this.cbproxy.begin_Init(names.ToArray()).whenCompleted(this.Init, this.FailureCallback);
       }
    
    What am I doing wrong?
  • xdm
    xdm La Coruña, Spain
    Your call to whenCompleted is wrong, the arguments for whenCompleted are the delegates to handle success and failure conditions.

    Something like this should do the trick:
    public class SessionCallbackAdapter : ChatRoomCallbackAdapter
    {
        //...
        public override void Init(List<String> names)
        {
            this.cbproxy.begin_Init(names.ToArray()).whenCompleted(
                                           this.Success, this.Failure);
        }
    
        public Success()
        {
            // Nothing to do in chat demo.
        }
    
        public Failure(Ice.Exception ex)
        {
            // Handle exception here. Destroy the session, log or whatever 
        }
    }
    
  • I see.. As it is in c++ server. I just didn't pay attention for that) Thanks!