/// <summary> /// This is the second important method, which creates /// the proxy, subscribe to connection state events /// and open a connection with the service /// </summary> public void Connect() { if (_channel == null) { try { _localClient = new SharedComponents.Client { Name = _viewModel.Name, AvatarID = _viewModel.SelectedIndex }; InstanceContext context = new InstanceContext(this); //As the address in the configuration file is set to localhost //we want to change it so we can call a service in internal //network, or over internet string servicePath = "/WPFHost/tcp"; string[] address = _viewModel.ConnectionIP.Split(':'); var binding = new NetTcpBinding("NetTcpBinding"); var endAdd = new EndpointAddress("net.tcp://" + address[0] + ":" + address[1] + servicePath); _channel = new WcfChatClient(context, binding, endAdd); _channel.Open(); _channel.InnerDuplexChannel.Faulted += InnerDuplexChannel_Faulted; _channel.InnerDuplexChannel.Opened += InnerDuplexChannel_Opened; _channel.InnerDuplexChannel.Closed += InnerDuplexChannel_Closed; _channel.SetProxy(_channel.ChannelFactory.CreateChannel()); _channel.ConnectCompleted += proxy_ConnectCompleted; //_channel.Connect(_localClient); //_channel.ConnectCompleted += (proxy_ConnectCompleted); _messages.Clear(); _msgIds.Clear(); //load all previous messages from database _channel.ConnectAsync(_localClient); //proxy_ConnectCompleted(output); using (var temp = new ChatDataContainer()) { var user = temp.ChatUsersSet.Where(s => s.Username == _viewModel.Name).ToList(); if (user.Count == 0) { var newuser = new ChatUsers { AvatarID = _viewModel.SelectedIndex, Username = _viewModel.Name }; temp.ChatUsersSet.Add(newuser); temp.SaveChanges(); } var cur = temp.ChatUsersSet.SingleOrDefault(t => t.Username == _viewModel.Name); if (cur != null) { long id = cur.Id; var userlist = temp.ChatUsersSet.Select(s => new { ID = s.Id, Avatar = s.AvatarID, Name = s.Username }); foreach (var row in temp.ChatDataSet.Where(s => s.Id == id)) { var currentUser = userlist.Where(s => s.ID == row.Id).ToList(); ListBoxItem item = MakeItem(currentUser[0].Avatar, currentUser[0].Name + " : " + row.Message); _viewModel.ChatMsgs.Add(item); _messages.Add(row.Message); _msgIds.Add(currentUser[0].Name); _viewModel.ScrollDown(); } } } } catch (Exception ex) { _viewModel.Name = ex.Message; _viewModel.ChatStatusLabel = "Offline"; _viewModel.ConnectButtonIsEnabled = true; } } else { HandleProxy(); } }
/// <summary> /// Cascade for pressing connect button /// </summary> public void buttonConnect_Click() { _channel = null; Connect(); }
/// <summary> /// This is the most method I like, it helps us alot /// We may can't know when a connection is lost in /// of network failure or service stopped. /// And also to maintain performance client doesnt know /// that the connection will be lost when hitting the /// disconnect button, but when a session is terminated /// this method will be called, and it will handle everything. /// </summary> private void HandleProxy() { if (_channel != null) { switch (_channel.State) { case CommunicationState.Closed: _channel = null; _viewModel.CloseConnection(); break; case CommunicationState.Closing: break; case CommunicationState.Created: break; case CommunicationState.Faulted: _channel.Abort(); _channel = null; _viewModel.CloseConnection(); break; case CommunicationState.Opened: Dictionary<int, Image> images = GetImages(); _viewModel.OpenConnection(_localClient.Name, images); break; case CommunicationState.Opening: break; } } }