converting wcf chatroom program from c# to vb.net

There is a chatroom program by Nikola Paljetak in c# useing wcf. Here is the link
http://www.ms.phy.hr/wcfchat/

I tried to convert it vb .net. I was somewhat successful but it does not work correctly. the Broadcast function does not send message to everyone in the chatroom. And looks like there are other problems.

Can you please help me to debug this program?

 

Here is the converted code in vb.net

———————————————————————————————

    _
        Public Class ChatService
        Implements IChat

        Private Shared syncObj As New Object()

        Private callback As IChatCallback = Nothing

        Public Delegate Sub ChatEventHandler(ByVal sender As Object, ByVal e As ChatEventArgs)
        Public Shared Event ChatEvent As ChatEventHandler

        Shared chatters As New Dictionary(Of String, ChatEventHandler)()

        Private name As String
        Private myEventHandler1 As ChatEventHandler

        Public Function Join(ByVal name As String) As String() Implements IChat.Join
            Dim userAdded As Boolean = False
            myEventHandler1 = New ChatEventHandler(AddressOf MyEventHandler2)

            SyncLock syncObj
                If Not chatters.ContainsKey(name) AndAlso name <> “” AndAlso name IsNot Nothing Then
                    Me.name = name
                    chatters.Add(name, AddressOf MyEventHandler2)
                    userAdded = True
                End If
            End SyncLock

            If userAdded Then
                callback = OperationContext.Current.GetCallbackChannel(Of IChatCallback)()
                Dim e As New ChatEventArgs()
                e.msgType = MessageType.UserEnter
                e.name = name
                BroadcastMessage(e)

                AddHandler ChatEvent, AddressOf myEventHandler1.Invoke ‘???

                Dim list As String() = New String(chatters.Count – 1) {}
                SyncLock syncObj
                    chatters.Keys.CopyTo(list, 0)
                End SyncLock
                Return list
            Else
                Return Nothing
            End If
        End Function

        Public Sub Say(ByVal msg As String) Implements IChat.Say
            Dim e As New ChatEventArgs()
            e.msgType = MessageType.Receive
            e.name = Me.name
            e.message = msg
            BroadcastMessage(e)
        End Sub

        Public Sub Whisper(ByVal [to] As String, ByVal msg As String) Implements IChat.Whisper
            Dim e As New ChatEventArgs()
            e.msgType = MessageType.ReceiveWhisper
            e.name = Me.name
            e.message = msg
            Try
                Dim chatterTo As ChatEventHandler
                SyncLock syncObj
                    chatterTo = chatters([to])
                End SyncLock
                chatterTo.BeginInvoke(Me, e, New AsyncCallback(AddressOf EndAsync), Nothing)
            Catch generatedExceptionName As KeyNotFoundException
            End Try
        End Sub

        Public Sub Leave() Implements IChat.Leave
            If Me.name Is Nothing Then
                Return
            End If

            SyncLock syncObj
                chatters.Remove(Me.name)
            End SyncLock

            RemoveHandler ChatEvent, AddressOf MyEventHandler2 ‘???

            Dim e As New ChatEventArgs()
            e.msgType = MessageType.UserLeave
            e.name = Me.name
            Me.name = Nothing
            BroadcastMessage(e)
        End Sub

        Private Sub MyEventHandler2(ByVal sender As Object, ByVal e As ChatEventArgs)
            Try
                Select Case e.msgType
                    Case MessageType.Receive
                        callback.Receive(e.name, e.message)
                        Exit Select
                    Case MessageType.ReceiveWhisper
                        callback.ReceiveWhisper(e.name, e.message)
                        Exit Select
                    Case MessageType.UserEnter
                        callback.UserEnter(e.name)
                        Exit Select
                    Case MessageType.UserLeave
                        callback.UserLeave(e.name)
                        Exit Select
                End Select
            Catch
                Leave()
            End Try
        End Sub

        Private Sub BroadcastMessage(ByVal e As ChatEventArgs)

            Dim temp As ChatEventHandler = myEventHandler1 ‘????

            If temp IsNot Nothing Then
                For Each handler As ChatEventHandler In temp.GetInvocationList()
                    handler.BeginInvoke(Me, e, New AsyncCallback(AddressOf EndAsync), Nothing)
                Next
            End If
        End Sub

        Private Sub EndAsync(ByVal ar As IAsyncResult)
            Dim d As ChatEventHandler = Nothing

            Try
                Dim asres As System.Runtime.Remoting.Messaging.AsyncResult = DirectCast(ar, System.Runtime.Remoting.Messaging.AsyncResult)
                d = DirectCast(asres.AsyncDelegate, ChatEventHandler)
                d.EndInvoke(ar)
            Catch
                RemoveHandler ChatEvent, AddressOf d.Invoke ‘???
            End Try
        End Sub

        Public Enum MessageType
            Receive
            UserEnter
            UserLeave
            ReceiveWhisper
        End Enum

        Public Class ChatEventArgs
            Inherits EventArgs
            Public msgType As MessageType
            Public name As String
            Public message As String
        End Class
    End Class

————————————————————————————-

And here is the code in c#

 

    [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IChatCallback))]
    interface IChat
    {
        [OperationContract(IsOneWay = false, IsInitiating = true, IsTerminating = false)]
        string[] Join(string name);

        [OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = false)]
        void Say(string msg);

        [OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = false)]
        void Whisper(string to, string msg);

        [OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = true)]
        void Leave();
    }

    interface IChatCallback
    {
        [OperationContract(IsOneWay = true)]
        void Receive(string senderName, string message);

        [OperationContract(IsOneWay = true)]
        void ReceiveWhisper(string senderName, string message);

        [OperationContract(IsOneWay = true)]
        void UserEnter(string name);

        [OperationContract(IsOneWay = true)]
        void UserLeave(string name);
    }

    public enum MessageType { Receive, UserEnter, UserLeave, ReceiveWhisper };

    public class ChatEventArgs : EventArgs
    {
        public MessageType msgType;
        public string name;
        public string message;
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class ChatService : IChat
    {

        private static Object syncObj = new Object();

        IChatCallback callback = null;

        public delegate void ChatEventHandler(object sender, ChatEventArgs e);
        public static event ChatEventHandler ChatEvent;

        static Dictionary chatters = new Dictionary();

        private string name;
        private ChatEventHandler myEventHandler = null;

        public string[] Join(string name)
        {
            bool userAdded = false;
            myEventHandler = new ChatEventHandler(MyEventHandler);

            lock (syncObj)
            {
                if (!chatters.ContainsKey(name) && name != “” && name != null)
                {
                    this.name = name;
                    chatters.Add(name, MyEventHandler);
                    userAdded = true;
                }
            }

            if (userAdded)
            {
                callback = OperationContext.Current.GetCallbackChannel();
                ChatEventArgs e = new ChatEventArgs();
                e.msgType = MessageType.UserEnter;
                e.name = name;
                BroadcastMessage(e);
                ChatEvent += myEventHandler;
                string[] list = new string[chatters.Count];
                lock (syncObj)
                {
                    chatters.Keys.CopyTo(list, 0);
                }
                return list;
            }
            else
            {
                return null;
            }
        }

        public void Say(string msg)
        {
            ChatEventArgs e = new ChatEventArgs();
            e.msgType = MessageType.Receive;
            e.name = this.name;
            e.message = msg;
            BroadcastMessage(e);
        }

        public void Whisper(string to, string msg)
        {
            ChatEventArgs e = new ChatEventArgs();
            e.msgType = MessageType.ReceiveWhisper;
            e.name = this.name;
            e.message = msg;
            try
            {
                ChatEventHandler chatterTo;
                lock (syncObj)
                {
                    chatterTo = chatters[to];
                }
                chatterTo.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
            }
            catch (KeyNotFoundException)
            {
            }
        }

        public void Leave()
        {
            if (this.name == null)
                return;

            lock (syncObj)
            {
                chatters.Remove(this.name);
            }
            ChatEvent -= myEventHandler;
            ChatEventArgs e = new ChatEventArgs();
            e.msgType = MessageType.UserLeave;
            e.name = this.name;
            this.name = null;
            BroadcastMessage(e);
        }

        private void MyEventHandler(object sender, ChatEventArgs e)
        {
            try
            {
                switch (e.msgType)
                {
                    case MessageType.Receive:
                        callback.Receive(e.name, e.message);
                        break;
                    case MessageType.ReceiveWhisper:
                        callback.ReceiveWhisper(e.name, e.message);
                        break;
                    case MessageType.UserEnter:
                        callback.UserEnter(e.name);
                        break;
                    case MessageType.UserLeave:
                        callback.UserLeave(e.name);
                        break;
                }
            }
            catch
            {
                Leave();
            }
        }

        private void BroadcastMessage(ChatEventArgs e)
        {

            ChatEventHandler temp =ChatEvent;

            if (temp != null)
            {
                foreach (ChatEventHandler handler in temp.GetInvocationList())
                {
                    handler.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
                }
            }
        }

        private void EndAsync(IAsyncResult ar)
        {
            ChatEventHandler d = null;

            try
            {
                System.Runtime.Remoting.Messaging.AsyncResult asres = (System.Runtime.Remoting.Messaging.AsyncResult)ar;
                d = ((ChatEventHandler)asres.AsyncDelegate);
                d.EndInvoke(ar);
            }
            catch
            {
                ChatEvent -= d;
            }
        }

    }