一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

SignalR进行实时通信两个案例分享

时间:2015-11-20 编辑:简简单单 来源:一聚教程网

案例一 实现在线聊天


在这里为了简单起见,暂时不涉及到数据库的操作。

类的定义

用户信息类UserInfo

    public class UserInfo
    {
        ///


        /// ConnectionId
        ///

        public string ConnectionId { get; set; }
        ///
        /// 姓名
        ///

        public string Name { get; set; }
        ///
        /// 上线时间
        ///

        public DateTime ConnectedAt { get; set; }
        ///
        /// 在线标志
        ///

        public bool IsOnline { get; set; }
    }

各块功能


后台


上线

    public override Task OnConnected()
    {
        Interlocked.Increment(ref _usersCount);
        var user = new UserInfo()
        {
            ConnectionId = Context.ConnectionId,
            IsOnline = true,
            Name = "user" + _usersCount,
            ConnectedAt = DateTime.Now
        };
        _users[Context.ConnectionId] = user;
        var notifyAll = (Task)Clients.All.NewUserNotification(user);
        var updateMessage = (Task)Clients.Caller.UpdateMessage(user.Name, _users.Values.ToArray());
        var sendToAll = (Task)Clients.Others.welcome(_users.Values.ToArray());
        return notifyAll.ContinueWith(_ => updateMessage).ContinueWith(_ => sendToAll);
    }

下线

    public override Task OnDisconnected()
    {
        UserInfo user;
        if (_users.TryRemove(Context.ConnectionId, out user))
        {
            return Clients.All.UserDisconnectedNotification(user);
        }
        return base.OnDisconnected();
    }

修改昵称

    public Task ChangeNickname(string newName)
    {
        UserInfo user;
        if (_users.TryGetValue(Context.ConnectionId, out user))
        {
            var oldName = user.Name;
            user.Name = newName;
            return Clients.All.NicknameChangedNotification(user, oldName);
        }
        return null;
    }

发送消息给所有人

    public Task Send(string message)
    {
        UserInfo user;
        if (_users.TryGetValue(Context.ConnectionId, out user))
        {
            var msgToSend = string.Format("[{0}]: {1}", user.Name, message);
            return Clients.All.Message(msgToSend);
        }
        return null;
    }

前台


用户上线消息

    function newUserNotification(user) {
        if (getUserElement(user.ConnectionId).length == 0) {
            $("#users").append($(getUserListItem(user)));
        }
        systemMessage("欢迎 " + user.Name + " 用户进入聊天室!");
    }

昵称改变消息

    function nicknameChangedNotification(user, oldName) {
        var userElement = getUserElement(user.ConnectionId);
        if (userElement.length > 0) {
            userElement.replaceWith($(getUserListItem(user)));
            systemMessage(oldName + " 改名为 " + user.Name + ".");
        }
        if (user.Id === $.connection.hub.id) {
            $("#name").text(user.Name);
        }

用户下线消息

    function userDisconnectedNotification(user) {
        var userElement = getUserElement(user.ConnectionId);
        if (userElement.length > 0) {
            systemMessage(user.Name + " 离开聊天室.");
            userElement.remove();
        }
    }

更新个人信息

    function updateMessage(assignedNickname, userList) {
        var result = "";
        for (var i = 0; i < userList.length; i++) {
            var user = userList[i];
            result += getUserListItem(user);
        }
        $("#users").empty();
        $("#users").append(result);
        $("#username").text(assignedNickname);
        $("#user-info").show();
    }

用户上线提醒

    function welcome(userList) {
        var result = "";
        for (var i = 0; i < userList.length; i++) {
            var user = userList[i];
            result += getUserListItem(user);
        }
        $("#users").empty();
        $("#users").append(result);
    }

发送消息

    function message(message) {
    var $panel = $("#chatpanel");
    $panel.append("

  • " + message + "
  • ");
        $panel.scrollTop($panel[0].scrollHeight);
        }

    效果图


    结束语

    功能较为简单,本来还加了其他的功能,但是由于最近太忙了,打好了一半然后又全部删掉了,后面有时间再慢慢加上去。


    案例二 在一个画板上画画实时在其他客户端上显示


    配置Hub

    在Startup中进行配置:

        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }

    建立DrawingHub

        public class Drawing : Hub
        {
            private const int Board, Board;
            private static int[,] _buffer = new int[BoardWidth, BoardHeight];
            public Task BroadcastPoint(int x, int y)
            {
                if (x < 0) x = 0;
                if (x >= BoardWidth) x = BoardWidth - 1;
                if (y < 0) y = 0;
                if (y >= BoardHeight) y = BoardHeight - 1;
                int color = 0;
                int.TryParse(Clients.Caller.color, out color);
                _buffer[x, y] = color;
                return Clients.Others.DrawPoint(x, y, Clients.Caller.color);
            }
            public Task BroadcastClear()
            {
                _buffer = new int[BoardWidth, BoardHeight];
                return Clients.Others.Clear();
            }
            public override Task OnConnected()
            {
                return Clients.Caller.Update(_buffer);
            }
        }

        用一个二位数组来缓存画板,一共就三个方法
        1. 当客户端连接时调用Update()方法刷新整个画板
        2. BroadcastClear()是点击清除按钮时讲整个画板擦出
        3. 最后一个就是画画方法,客户端按下鼠标画画时,调用该方法进行绘制。

    页面

       
       
       
            Drawing board
           
           
           
           
           
       
       
           


               

                   
                    <select id="color">
                   
               

               
               

                   
               

           

       
       

        页面非常简单,一个选择颜色的下拉框,一个画板,和一个清除按钮。

    javascript

        $(function () {
        //初始化
            var colors = ["black", "red", "green", "blue", "yellow", "magenta", "white"];
            var canvas = $("#canvas");
            var colorElement = $("#color");
            for (var i = 0; i < colors.length; i++) {
                colorElement.append(
                    "

    热门栏目