基于sliverlight + wcf的web 文字版IM 示例

演示地址: http://task.24city.com/default.html

预览界面:

一、布局 采用Grid布局,5行2列 第一行:为登录/注册信息区 第二行:左列为聊天记录区,右列为"最近联系人,我的好友,当前在线"等常见功能区 第三行:显示当前聊天对象以及"加为好友","从好友列表中删除"二个按钮 第四行: 打字聊天栏 第五行:发送按钮

二、机制 a.采用wcf通讯,silverlight调用wcf得到返回结果和发送聊天内容,wcf与数据库交互----即silverlight以wcf为桥梁来操作数据库 b.聊天记录的刷新采用Timer定时器,每隔5秒通过调用wcf更新 c.在线列表利用website中的Global全局字典来实现,每登录或注销一个用户时,均通过wcf向该字典中插入或删除指定key的"记录"

三、一些小技巧:

a.Ctrl+回车 键发送的实现代码:

private void txtContent_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            ModifierKeys keys = Keyboard.Modifiers;
            if (e.Key == Key.Enter && keys == ModifierKeys.Control)
            {
                btnSend_Click(sender, e);
            }
        }

b.TabControl中加载ListBox并附加滚动条的代码:

ListBox _listBox = new ListBox();
_listBox.ItemsSource = _list;
_listBox.DisplayMemberPath = "Value";
_listBox.MouseLeftButtonUp += new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
ScrollViewer _viewer = new ScrollViewer();
_viewer.Content = _listBox;
_listBox.BorderThickness = new Thickness(0);
this.tblItemRecently.Content = _viewer;
_viewer.Height = pnlTab.ActualHeight - 38;

即TabItem的Content指定为一个ScrollViewer,而这个ScrollViewer的Content再指定为ListBox,用二层嵌套实现

c.客户端登录Ip的取得

silverlight并不能直接取得IP地址,所以这里用website中的wcf做了中转,xap加载时就先利用wcf取回当前Ip,呵 四、代码 代码有点乱,也相对比较长,关键代码全部折叠贴在下面了:

<UserControl xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"  xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"  x:Class="Talker.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d">
    <Grid x:Name="LayoutRoot" ShowGridLines="False">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="250"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="35"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="35"></RowDefinition>
            <RowDefinition Height="60"></RowDefinition>
            <RowDefinition Height="35"></RowDefinition>
        </Grid.RowDefinitions>
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2" x:Name="pnlLogin" Visibility="Collapsed">
            <dataInput:Label Content="用户名:" VerticalAlignment="Center" HorizontalAlignment="Center" ></dataInput:Label>
            <TextBox Width="100" x:Name="txtLoginName" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBox>
            <dataInput:Label Content="密 码:" Margin="3,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center" ></dataInput:Label>
            <PasswordBox Width="100" x:Name="txtPwd" VerticalAlignment="Center" HorizontalAlignment="Center"></PasswordBox>
            <Button Content="登录" Width="60" Margin="3,0,0,0" x:Name="btnLogin" Click="btnLogin_Click" VerticalAlignment="Center" HorizontalAlignment="Center" ></Button>
            <Button Content="注册" Width="60" Margin="3,0,0,0" x:Name="btnGoToReg" Click="btnGoToReg_Click" VerticalAlignment="Center" HorizontalAlignment="Center" ></Button>
        </StackPanel>

        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2" x:Name="pnlReg">
            <dataInput:Label Content="用户名:" VerticalAlignment="Center" ></dataInput:Label>
            <TextBox Width="90" x:Name="txtRegName" VerticalAlignment="Center"></TextBox>
            <dataInput:Label Content="呢称:" Margin="3,0,0,0" VerticalAlignment="Center"></dataInput:Label>
            <TextBox Width="90" x:Name="txtNickName" VerticalAlignment="Center"></TextBox>
            <dataInput:Label Content="密 码:" Margin="3,0,0,0" VerticalAlignment="Center" ></dataInput:Label>
            <PasswordBox Width="60" x:Name="txtRegPwd" VerticalAlignment="Center"></PasswordBox>
            <dataInput:Label Content="再次输入密码:" Margin="3,0,0,0" VerticalAlignment="Center" ></dataInput:Label>
            <PasswordBox Width="60" x:Name="txtRegPwd2" VerticalAlignment="Center"></PasswordBox>
            <Button Content="注册" Width="50" Margin="3,0,0,0" x:Name="btnReg" VerticalAlignment="Center" Click="btnReg_Click"></Button>
            <Button Content="返回登录" Width="60" Margin="3,0,0,0" x:Name="btnBackToLogin" Click="btnBackToLogin_Click" VerticalAlignment="Center"  ></Button>
        </StackPanel>
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2" x:Name="pnlLoginOk" Visibility="Collapsed">
            <TextBlock x:Name="txtLoginOk" Text="1^yjmyzz@126.com@^菩提树下的杨过" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
            <Button Content="退出" Margin="3,0,0,0" x:Name="btnLogOut" Width="50" VerticalAlignment="Center" HorizontalAlignment="Center" Click="btnLogOut_Click" ></Button>
        </StackPanel>
        <TextBox Grid.Row="1" Grid.Column="0" TextWrapping="Wrap" Text="" IsReadOnly="True" x:Name="txtRecord" VerticalScrollBarVisibility="Auto"></TextBox>
        <StackPanel Grid.Row="1" Grid.Column="1" x:Name="pnlTab">
            <controls:TabControl x:Name="tblTitle" Margin="3,0,0,0">
                <controls:TabItem Header="最近联系人" x:Name="tblItemRecently" MouseLeftButtonUp="tblItemRecently_MouseLeftButtonUp" />
                <controls:TabItem Header="我的好友" x:Name="tblItemMyFriend" MouseLeftButtonUp="tblItemMyFriend_MouseLeftButtonUp" />
                <controls:TabItem Header="当前在线" x:Name="tblItemOnline" MouseLeftButtonUp="tblItemOnline_MouseLeftButtonUp" />
            </controls:TabControl>
        </StackPanel>
        <StackPanel Grid.Row="2" Grid.ColumnSpan="2" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3,0,0,0">
            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">
                <Run>您正在跟 </Run>
                <Run Foreground="Red" x:Name="txtTarget"></Run>
                <Run> 聊天:</Run>
            </TextBlock>
            <Button x:Name="btnAddFriend"  Content="加为好友" Width="60" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="3,0,0,0" Click="btnAddFriend_Click" Visibility="Collapsed" />
            <Button x:Name="btnDeleteFriend"  Content="从好友列表中删除" Width="140" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="3,0,0,0" Click="btnDeleteFriend_Click" Visibility="Collapsed" />
            <dataInput:Label x:Name="lblId" Visibility="Collapsed" Content=""></dataInput:Label>
        </StackPanel>

        <TextBox x:Name="txtContent" Text="" Grid.Row="3" Grid.ColumnSpan="2" KeyDown="txtContent_KeyDown" GotFocus="txtContent_GotFocus"></TextBox>
        <TextBlock Text="按“Ctrl+回车”发送" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center"></TextBlock>
        <Button x:Name="btnSend" Grid.Row="4" Grid.Column="1" Content="发送" Width="80" HorizontalAlignment="Right" VerticalAlignment="Center" Click="btnSend_Click" ></Button>
   

    </Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Json;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Talker.BLL;
using Talker.Entity;
namespace Talker
{
    public partial class MainPage : UserControl
    {
        string _wcfBasePath = "http://localhost:9002/Wcf/talk.svc/";
        string _Ip = "";
        private DispatcherTimer _timer;
       
        public MainPage()
        {
            InitializeComponent();
            GetIP();
            ShowLogin();          
        }
        /**//// <summary>
        /// 格式化登录信息
        /// </summary>
        /// <returns></returns>
        string FormatLoginInfo()
        {
            string[] _arr = Helper.GetLoginInfo().Split('^');
            return "欢迎回来 " + _arr[1] + "(" + _arr[2] + "),最近登录时间:" + _arr[3]&nbnbsp;+ ",最近登录Ip:" + _arr[4];
        }
        /**//// <summary>
        /// 显示登录面板
        /// </summary>
        void ShowLogin()
        {
            if (Helper.IsLogined())
            {
                pnlLoginOk.Visibility = Visibility.Visible;
                pnlLogin.Visibility = Visibility.Collapsed;
                pnlReg.Visibility = Visibility.Collapsed;
                txtLoginOk.Text = FormatLoginInfo();
                //向服务器在线列表中添加自己
                InsertOnline();
                //获取历史聊天记录
                GetMessageList();
                //获取最近联系人
                GetRecentList();

                this._timer = new DispatcherTimer();
                this._timer.Interval = new TimeSpan(0, 0, 5);
                this._timer.Tick += new EventHandler(timer_Tick);
                this._timer.Start();
            }
            else
            {
                pnlLogin.Visibility = Visibility.Visible;
                pnlLoginOk.Visibility = Visibility.Collapsed;
                pnlReg.Visibility = Visibility.Collapsed;
            }

        }
        /**//// <summary>
        /// 出错提示
        /// </summary>
        /// <param name="title"></param>
        /// <param name="content"></param>
        void ShowError(string title, string content)
        {
            //txtError.Text = "错误:" + err;
            //pnlError.Visibility = Visibility.Visible;
            ChildWindow child = new ChildWindow();
            child.Title = title;
            child.Content = content;
            child.HasCloseButton = true;
            child.OverlayBrush = new SolidColorBrush(Colors.Gray);
            child.OverlayOpacity = 0.3;
            child.Width = 240;
            child.Height = 100;
            child.Show();
        }
        void ShowError(string content)
        {
            ShowError("错误", content);
        }
        /**//// <summary>
        /// 获取当前客户端IP
        /// </summary>
        private void GetIP()
        {
            Uri serviceUri = new Uri(_wcfBasePath + "GetIP?rnd=" + DateTime.Now.Ticks);
            WebClient client = new WebClient();
            client.OpenReadCompleted += new OpenReadCompletedEventHandler(GetIpComplete);
            client.OpenReadAsync(serviceUri);
        }
        void GetIpComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jResult = JsonArray.Load(e.Result);
                _Ip = _jResult["IP"].ToString().Trim('\"');
            }
        }
        /**//// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLogin_Click(object sender, System.Windows.RoutedEventArgs e)
        {

            Uri serviceUri = new Uri(_wcfBasePath + "IsValidUser?loginName=" + HttpUtility.UrlEncode(txtLoginName.Text.Trim()) + "&pwd=" + HttpUtility.UrlEncode(txtPwd.Password.Trim()) + "&rnd=" + DateTime.Now.Ticks);
            WebClient client = new WebClient();
            client.OpenReadCompleted += new OpenReadCompletedEventHandler(loginComplete);
            client.OpenReadAsync(serviceUri);
        }
        /**//// <summary>
        /// 登录完毕回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void loginComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jResult = JsonArray.Load(e.Result);
                if (_jResult["Head"].Count == 0)
                {
                    ShowError("登录失败,请检查用户名/密码");
                }
                else
                {
                    var dr = _jResult["Head"][0];
                    T_User _user = new T_User();
                    _user.F_Id = int.Parse(dr["F_Id"].ToString().Trim('\"'));
                    //_user.F_LastLoginDate = DateTime.Parse(dr["F_LastLoginDate"].ToString().Trim('\"'));
                    _user.F_LastLoginDate = DateTime.Now;
                    //_user.F_LastLoginIP = dr["F_LastLoginIp"].ToString().Trim('\"');
                    _user.F_LastLoginIP = _Ip;
                    _user.F_LoginName = dr["F_LoginName"].ToString().Trim('\"');
                    _user.F_NickName = dr["F_NickName"].ToString().Trim('\"');
                    _user.F_Pwd = "";
                    Helper.WriteLoginInfo(_user);
                    pnlLoginOk.Visibility = Visibility.Visible;
                    pnlLogin.Visibility = Visibility.Collapsed;
                    txtLoginOk.Text = FormatLoginInfo();
                    InsertOnline();
                    //获取历史聊天记录
                    GetMessageList();
                    //获取最近联系人
                    GetRecentList();

                    this._timer = new DispatcherTimer();
                    this._timer.Interval = new TimeSpan(0, 0, 0, 5);
                    this._timer.Tick += new EventHandler(timer_Tick);
                    this._timer.Start();
                }
            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }
        /**//// <summary>
        /// 返回登录 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnBackToLogin_Click(object sender, RoutedEventArgs e)
        {
            pnlReg.Visibility = Visibility.Collapsed;
            pnlLogin.Visibility = Visibility.Visible;
        }
        /**//// <summary>
        /// 返回注册
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGoToReg_Click(object sender, RoutedEventArgs e)
        {
            pnlLogin.Visibility = Visibility.Collapsed;
            pnlReg.Visibility = Visibility.Visible;
        }

        /**//// <summary>
        /// 退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLogOut_Click(object sender, RoutedEventArgs e)
        {
            pnlLogin.Visibility = Visibility.Visible;
            pnlLoginOk.Visibility = Visibility.Collapsed;
            DeleteOnline();
            Helper.DeleteLoginInfo();
            if (_timer != null)
            {
                _timer.Stop();
            }

        }

        /**//// <summary>
        /// (登录后)插入在线列表
        /// </summary>
        void InsertOnline()
        {
            string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            Uri serviceUri = new Uri(_wcfBasePath + "InsertOnline?userid=" + HttpUtility.UrlEncode(_loginInfo[0]) + "&loginname=" + HttpUtility.UrlEncode(_loginInfo[1]) + "&nickname=" + HttpUtility.UrlEncode(_loginInfo[2]) + "&rnd=" + DateTime.Now.Ticks);
            WebClient client = new WebClient();
            client.OpenReadAsync(serviceUri);
        }
        /**//// <summary>
        /// (退出时)从在线列表清除
        /// </summary>
        void DeleteOnline()
        {
            string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            Uri serviceUri = new Uri(_wcfBasePath + "DeleteOnline?userid=" + _loginInfo[0] + "&rnd=" + DateTime.Now.Ticks);
            WebClient client = new WebClient();
            client.OpenReadAsync(serviceUri);
        }
        /**//// <summary>
        /// 点击"在线用户"时,更新在线列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tblItemOnline_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Uri serviceUri = new Uri(_wcfBasePath + "GetOnlineList?&rnd=" + DateTime.Now.Ticks);
            WebClient client = new WebClient();
            client.OpenReadCompleted += new OpenReadCompletedEventHandler(GetOnlineListComplete);
            client.OpenReadAsync(serviceUri);
        }

        /**//// <summary>
        /// 取得在线列表回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GetOnlineListComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jsonValue = JsonArray.Load(e.Result);
                List<KeyValuePair<int, string>> _list = new List<KeyValuePair<int, string>>();
                if (_jsonValue["Head"].Count > 0)
                {
                    for (int i = 0; i < _jsonValue["Head"].Count; i++)
                    {
                        _list.Add(new KeyValuePair<int, string>(int.Parse(_jsonValue["Head"][i]["ID"].ToString().Trim('\"')), _jsonValue["Head"][i]["Name"].ToString().Trim('\"')));
                    }
                }
                else
                {
                    _list.Add(new KeyValuePair<int, string>(0, "暂无在线用户"));
                }

                ListBox _listBox = new ListBox();
                _listBox.ItemsSource = _list;
                _listBox.DisplayMemberPath = "Value";
                _listBox.MouseLeftButtonUp += new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
                ScrollViewer _viewer = new ScrollViewer();
                _viewer.Content = _listBox;
                _listBox.BorderThickness = new Thickness(0);
                this.tblItemOnline.Content = _viewer;
                _viewer.Height = pnlTab.ActualHeight - 38;

                //ListBox _listBox = new ListBox();
                //_listBox.ItemsSource = _list;
                //_listBox.DisplayMemberPath = "Value";
                //this.tblItemOnline.Content = _listBox;
                //_listBox.MouseLeftButtonUp += new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }

        /**//// <summary>
        /// 列表框单击时显示“您正在跟xxx聊天”
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _listBox_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            ListBox lstBox = sender as ListBox;
            KeyValuePair<int, string> _keyValue = (KeyValuePair<int, string>)lstBox.SelectedItem;
            if (_keyValue.Key == 0) { return; }
            txtTarget.Text = _keyValue.Value;
            lblId.Content = _keyValue.Key.ToString();
        }
        /**//// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReg_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (this.txtRegName.Text == "")
            {
                ShowError("请输入注册登录名!");
                return;
            }

            if (txtRegPwd.Password != txtRegPwd2.Password)
            {
                ShowError("二次密码输入不一致!");
                return;
            }
            Uri serviceUri = new Uri(_wcfBasePath + "InsertUser?loginName=" + HttpUtility.UrlEncode(txtRegName.Text.Trim()) + "&nickName=" + HttpUtility.UrlEncode(this.txtNickName.Text.Trim()) + "&pwd=" + HttpUtility.UrlEncode(this.txtRegPwd.Password.Trim()) + "&rnd=" + DateTime.Now.Ticks);
            WebClient client = nbsp;new WebClient();
            client.OpenReadCompleted += new OpenReadCompletedEventHandler(RegComplete);
            client.OpenReadAsync(serviceUri);
        }
        /**//// <summary>
        /// 注册完成回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void RegComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jsonValue = JsonArray.Load(e.Result);
                if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
                {
                    //注册成功
                    ShowError("恭喜", "注册成功,请登录!");
                    pnlLogin.Visibility = Visibility.Visible;
                    pnlReg.Visibility = Visibility.Collapsed;
                    txtLoginName.Text = txtRegName.Text;
                    txtPwd.Password = txtRegPwd.Password;

                }
                else
                {
                    ShowError("注册失败:" + _jsonValue["detail"].ToString().Trim('\"'));
                }
            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }

        /**//// <summary>
        /// 点击"我的好友"时,更新列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tblItemMyFriend_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            int _userId = 0;
            if (int.TryParse(_loginInfo[0].ToString(), out _userId))
            {
                Uri serviceUri = new Uri(_wcfBasePath + "GetFriendList?userId=" + _loginInfo[0] + "&rnd=" + DateTime.Now.Ticks);
                WebClient client = new WebClient();
                client.OpenReadCompleted += new OpenReadCompletedEventHandler(GetFriendListComplete);
                client.OpenReadAsync(serviceUri);
            }
            else
            {
                tblItemMyFriend.Content = "尚未添加任何好友";
            }

        }
        /**//// <summary>
        /// 获取好友列表回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GetFriendListComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jsonValue = JsonArray.Load(e.Result);
                List<KeyValuePair<int, string>> _list = new List<KeyValuePair<int, string>>();
                if (_jsonValue["Head"].Count > 0)
                {
                    for (int i = 0; i < _jsonValue["Head"].Count; i++)
                    {
                        _list.Add(new KeyValuePair<int, string>(int.Parse(_jsonValue["Head"][i]["ID"].ToString().Trim('\"')), _jsonValue["Head"][i]["Name"].ToString().Trim('\"')));
                    }
                }
                else
                {
                    _list.Add(new KeyValuePair<int, string>(0, "尚未添加任何好友"));
                }
                ListBox _listBox = new ListBox();
                _listBox.ItemsSource = _list;
                _listBox.DisplayMemberPath = "Value";
                _listBox.MouseLeftButtonUp += new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
                ScrollViewer _viewer = new ScrollViewer();
                _viewer.Content = _listBox;
                _listBox.BorderThickness = new Thickness(0);
                this.tblItemMyFriend.Content = _viewer;
                _viewer.Height = pnlTab.ActualHeight - 38;
            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }

        /**//// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            int _userId = 0;
            if (int.TryParse(_loginInfo[0].ToString(), out _userId))
            {
                int _receiverId = 0;
                if (int.TryParse(this.lblId.Content.ToString(), out _receiverId))
                {
                    if (_userId == _receiverId)
                    {
                        ShowError("自己不能跟自己聊天!");
                        return;
                    }
                    if (txtContent.Text.Trim() == "")
                    {
                        ShowError("请输入聊天内容!");
                    }
                    else
                    {
                        Uri serviceUri = new Uri(_wcfBasePath + "SendMsg?senderId=" + _userId + "&receiverId=" + _receiverId + "&content=" + HttpUtility.UrlEncode(this.txtContent.Text) + "&rnd=" + DateTime.Now.Ticks);
                        WebClient client = new WebClient();
                        client.OpenReadCompleted += new OpenReadCompletedEventHandler(SendMsgComplete);
                        client.OpenReadAsync(serviceUri);
                    }
                }
                else
                {
                    ShowError("请先从右侧列表中选择一个聊天对象");
                }
            }
            else
            {
                ShowError("请先登录");
            }
        }
        /**//// <summary>
        /// 发送消息回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void SendMsgComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jsonValue = JsonArray.Load(e.Result);
                if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
                {
                    this.txtContent.Text = "";
                    GetMessageList();
                }
            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }

        /**//// <summary>
        /// 获取消息记录
        /// </summary>
        void GetMessageList()
        {
            string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            int _userId = 0;
            if (int.TryParse(_loginInfo[0].ToString(), out _userId))
            {
                Uri serviceUri = new Uri(_wcfBasePath + "GetMessageList?userId=" + _userId + "&rnd=" + DateTime.Now.Ticks);
                WebClient client = new WebClient();
                client.OpenReadCompleted += new OpenReadCompletedEventHandler(GetMessageListComplete);
                client.OpenReadAsync(serviceUri);
            }
        }
        /**//// <summary>
        /// 取得消息列表回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GetMessageListComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jsonValue = JsonArray.Load(e.Result);
                StringBuilder sb = new StringBuilder();
                if (_jsonValue["Head"].Count > 0)
                {
                    string[] _loginInfo = Helper.GetLoginInfo().Split('^');
                    string _senderName = _loginInfo[1] + "(" + _loginInfo[2] + ")";
                    for (int i = 0; i < _jsonValue["Head"].Count; i++)
                    {
                        string _s = _jsonValue["Head"][i]["F_SenderName"].ToString().Trim('\"');
                        if (_s == _senderName)
                        {
                            _s = "我";
                        }
                        string _r = _jsonValue["Head"][i]["F_ReceiverName"].ToString().Trim('\"');
                        if (_r == _senderName)
                        {
                            _r = "我";
                        }
                        sb.Append(_s + " 于 " + _jsonValue["Head"][i]["F_Date"].ToString().Trim('\"') + " 对 " + _r + " 说:" + Environment.NewLine + _jsonValue["Head"][i]["F_Content"].ToString().Trim('\"') + Environment.NewLine + Environment.NewLine);
                    }
                    txtRecord.Text = sb.ToString();
                    txtRecord.SelectAll();
                }

            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }
        /**//// <summary>
        /// 取得最近联系人列表
        /// </summary>
        void GetRecentList()
        {
            string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            int _userId = 0;
            if (int.TryParse(_loginInfo[0].ToString(), out _userId))
            {
                Uri serviceUri = new Uri(_wcfBasePath + "GetRecent?userId=" + _userId + "&rnd=" + DateTime.Now.Ticks);
                WebClient client = new WebClient();
                client.OpenReadCompleted += new OpenReadCompletedEventHandler(GetRecentListComplete);
                client.OpenReadAsync(serviceUri);
            }
            else 
            {
                tblItemRecently.Content = "暂无联系人信息";
            }
        }

        /**//// <summary>
        /// 取得最近联系人列表回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GetRecentListComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jsonValue = JsonArray.Load(e.Result);
                List<KeyValuePair<int, string>> _list = new List<KeyValuePair<int, string>>();
                if (_jsonValue["Head"].Count > 0)
                {
                    for (int i = 0; i < _jsonValue["Head"].Count; i++)
                    {
                        _list.Add(new KeyValuePair<int, string>(int.Parse(_jsonValue["Head"][i]["ID"].ToString().Trim('\"')), _jsonValue["Head"][i]["Name"].ToString().Trim('\"')));
                    }
                }
                else
                {
                    _list.Add(new KeyValuePair<int, string>(0, "暂无任何人给你发消息"));
                }
                ListBox _listBox = new ListBox();
                _listBox.ItemsSource = _list;
                _listBox.DisplayMemberPath = "Value";
                _listBox.MouseLeftButtonUp += new MouseButtonEventHandler(_listBox_MouseLeftButtonUp);
                ScrollViewer _viewer = new ScrollViewer();
                _viewer.Content = _listBox;
                _listBox.BorderThickness = new Thickness(0);
                this.tblItemRecently.Content = _viewer;
                _viewer.Height = pnlTab.ActualHeight - 38;
            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }
        private void txtContent_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            ModifierKeys keys = Keyboard.Modifiers;
            if (e.Key == Key.Enter && keys == ModifierKeys.Control)
            {
                btnSend_Click(sender, e);
            }
        }
        private void tblItemRecently_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            GetRecentList();
        }
        private void txtContent_GotFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            int _myId = 0;
            if (int.TryParse(_loginInfo[0].ToString(), out _myId))
            {
                int _otherId = 0;
                if (int.TryParse(this.lblId.Content.ToString(), out _otherId))
                {
                    if (_myId == _otherId)
                    {
                        return;
                    }
                    Uri serviceUri = new Uri(_wcfBasePath + "IsFriend?myId=" + _myId + "&otherId=" + _otherId + "&rnd=" + DateTime.Now.Ticks);
                    WebClient client = new WebClient();
                    client.OpenReadCompleted += new OpenReadCompletedEventHandler(IsFriendComplete);
                    client.OpenReadAsync(serviceUri);
                }
            }
        }

        void IsFriendComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jsonValue = JsonArray.Load(e.Result);
                List<KeyValuePair<int, string>> _list = new List<KeyValuePair<int, string>>();
                if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
                {
                    this.btnDeleteFriend.Visibility = Visibility.Visible;
                    this.btnAddFriend.Visibility = Visibility.Collapsed;
                }
                else 
                {
                    this.btnAddFriend.Visibility = Visibility.Visible;
                    this.btnDeleteFriend.Visibility = Visibility.Collapsed;
                }
            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }
        /**//// <summary>
        /// 加为好友
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddFriend_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            int _myId = 0;
            if (int.TryParse(_loginInfo[0].ToString(), out _myId))
            {
                int _otherId = 0;
                if (int.TryParse(this.lblId.Content.ToString(), out _otherId))
                {
                    if (_myId == _otherId)
                    {
                        return;
                    }
                    Uri serviceUri = new Uri(_wcfBasePath + "InsertFriend?myId=" + _myId + "&otherId=" + _otherId + "&rnd=" + DateTime.Now.Ticks);
                    WebClient client = new WebClient();
                    client.OpenReadCompleted += new OpenReadCompletedEventHandler(AddFriendComplete);
                    client.OpenReadAsync(serviceUri);
                    btnAddFriend.Visibility = Visibility.Collapsed;
                }
            }
        }
        
        
        void AddFriendComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jsonValue = JsonArray.Load(e.Result);
                if (bool.Parse(_jsonValue["result"].ToString().Trim('\"'))){
                    this.tblItemMyFriend_MouseLeftButtonUp(sender,null);
                }
            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }
        /**//// <summary>
        /// 删除好友
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDeleteFriend_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            string[] _loginInfo = Helper.GetLoginInfo().Split('^');
            int _myId = 0;
            if (int.TryParse(_loginInfo[0].ToString(), out _myId))
            {
                int _otherId = 0;
                if (int.TryParse(this.lblId.Content.ToString(), out _otherId))
                {
                    if (_myId == _otherId)
                    {
                        return;
                    }
                    Uri serviceUri = new Uri(_wcfBasePath + "DeleteFriend?myId=" + _myId + "&otherId=" + _otherId + "&rnd=" + DateTime.Now.Ticks);
                    WebClient client = new WebClient();
                    client.OpenReadCompleted += new OpenReadCompletedEventHandler(DeleteFriendComplete);
                    client.OpenReadAsync(serviceUri);
                    btnDeleteFriend.Visibility = Visibility.Collapsed;

                }
            }
        }
        
        
        

        void DeleteFriendComplete(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                JsonValue _jsonValue = JsonArray.Load(e.Result);
                if (bool.Parse(_jsonValue["result"].ToString().Trim('\"')))
                {
                    this.tblItemMyFriend_MouseLeftButtonUp(sender, null);
                }
            }
            else
            {
                ShowError(e.Error.Message.ToString());
            }
        }

        void timer_Tick(object sender, EventArgs e)
        {
            GetMessageList();
        }
        private void txtContent_LostFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            this.btnAddFriend.Visibility = Visibility.Collapsed;
            this.btnDeleteFriend.Visibility = Visibility.Collapsed;            
        }
       
        
    }
}
1CREATE TABLE [dbo].[T_User](
 2    [F_Id] [int] IDENTITY(1,1) NOT NULL,
 3    [F_LoginName] [nvarchar](50) NOT NULL,
 4    [F_NickName] [nvarchar](100) NOT NULL,
 5    [F_Pwd] [nvarchar](50) NOT NULL,
 6    [F_LastLoginDate] [datetime] NOT NULL,
 7    [F_LastLoginIP] [nvarchar](50) NOT NULL,
 8 CONSTRAINT [PK_T_User] PRIMARY KEY CLUSTERED 
 9(
10    [F_Id] ASC
11)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
12) ON [PRIMARY]
13
14
15CREATE TABLE [dbo].[T_Message](
16    [F_Id] [int] IDENTITY(1,1) NOT NULL,
17    [F_ReceiverId] [int] NOT NULL,
18    [F_SenderId] [int] NOT NULL,
19    [F_Content] [nvarchar](max) NOT NULL,
20    [F_Date] [datetime] NOT NULL,
21 CONSTRAINT [PK_T_Message] PRIMARY KEY CLUSTERED 
22(
23    [F_Id] ASC
24)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
25) ON [PRIMARY]
26
27GO
28ALTER TABLE [dbo].[T_Message]  WITH CHECK ADD  CONSTRAINT [FK_T_Message_T_User] FOREIGN KEY([F_ReceiverId])
29REFERENCES [dbo].[T_User] ([F_Id])
30ON UPDATE CASCADE
31ON DELETE CASCADE
32GO
33ALTER TABLE [dbo].[T_Message] CHECK CONSTRAINT [FK_T_Message_T_User]
34
35CREATE TABLE [dbo].[T_Friend](
36    [F_Id] [int] IDENTITY(1,1) NOT NULL,
37    [F_UserId] [int] NOT NULL,
38    [F_FriendId] [int] NOT NULL,
39 CONSTRAINT [PK_T_Friend] PRIMARY KEY CLUSTERED 
40(
41    [F_Id] ASC
42)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
43) ON [PRIMARY]
44
45GO
46ALTER TABLE [dbo].[T_Friend]  WITH CHECK ADD  CONSTRAINT [FK_T_Friend_T_User1] FOREIGN KEY([F_UserId])
47REFERENCES [dbo].[T_User] ([F_Id])
48ON UPDATE CASCADE
49ON DELETE CASCADE
50GO
51ALTER TABLE [dbo].[T_Friend] CHECK CONSTRAINT [FK_T_Friend_T_User1]

本来是要把源代码放上来了,一来是因为完全是用来练手的,代码写得比较乱,二来这里面用到了公司的一些现成工具库的dll,不方便对外发布,所以只能把主要代码贴出来,其实只要弄懂了原理,大家完全可以自己从头开发一遍,说穿了就是silverlight + wcf + timer来读写数据库,没有太多的技术含量

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏木宛城主

SharePoint 2013 Step by Step——How to Create a Lookup Column to Another Site(Cross Site)

OverView In this post,I want to show u how to add a look up column in my list or...

20350
来自专栏跟着阿笨一起玩NET

C# 几种数据库的大数据批量插入

转载:http://www.cnblogs.com/luluping/archive/2012/08/09/2629515.html

41110
来自专栏互联网开发者交流社区

温湿度系统(花葵、库房检测)

11330
来自专栏智能大石头

SQLite事务与自增深度分析

SQLite什么都好,就怕“database is locked”这些年来想尽办法去规避它。 测试代码: static void Test2() { ...

20670
来自专栏挖掘大数据

常用的Hadoop 文件查看工具

packages.config <?xml version="1.0" encoding="utf-8"?> <packages> <package id...

21090
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(22)-权限管理系统-模块导航制作

最近比较忙,系统难度独步增加,文章的发布速度明显比以前慢了。 由于我们已经跑通了整个系统,所有东西都回到了简单,接下来我们做模块制作也就是操作SysModule...

29980
来自专栏ASP.NET MVC5 后台权限管理系统

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(23)-权限管理系统-角色组模块

接下来我们的目标是 角色组管理 角色组权限设置 用户管理 把角色组授权给用户 给用户分配角色组 所以最少我们还要讲多5讲才能结束这个管理系统,经过之前的样例程序...

33790
来自专栏互联网开发者交流社区

AvalonJS+MVVM实战部分源码

14820
来自专栏技术博客

一步一步学Linq to sql(二):DataContext与实体

 DataContext类型(数据上下文)是System.Data.Linq命名空间下的重要类型,用于把查询句法翻译成SQL语句,以及把数据从数据库返回给调用方...

12120
来自专栏阿炬.NET

asp.net mvc4 使用KindEditor文本编辑器

35570

扫码关注云+社区

领取腾讯云代金券