• HTML5示例之WebSocket


    Web应用程序通常有一些耗时的操作,但有些操作耗时不是很长,一分钟之内能完成。如果采用后台任务队列去异步处理,这样的用户不能实时看到后台处理的情况。倘若用户触发操作后,Web页面能够实时看到后台处理的进度,并且返回实时的状态,用户等待起来是不是感觉非常棒。下面是一个HTML5+ASP.NET MVC实现的示例。

    1.前端页面和脚本

    页面包含一个文本框和一个【提交】按钮,文本框输入后台要返回的消息数。

    <h2>WebSocket</h2>
    <div class="form-inline">
        <div class="form-group">
            <label for="count">消息数</label>
            <input type="text" class="form-control" id="count" placeholder="服务端返回的消息数">
        </div>
        <button class="btn btn-primary" onclick="wsTest()">提交</button>
    </div>
    <blockquote>
        <ol id="msg"></ol>
    </blockquote>
    

    WebSocket的api很简单,如下示例封装了一个简单的操作。

    var WsUtil = {
        msg: document.getElementById('msg'),
        ws: null,
        connect: function (url, callback) {
            var _this = this;
            _this.msg.innerHTML = '';
            _this.appendMsg('正在连接......', '#00f');
            _this.ws = new WebSocket(url);
            _this.ws.onopen = function () {
                _this.appendMsg('客户端已连接', '#00f');
                if (callback) {
                    callback(_this.ws);
                }
            }
            _this.ws.onmessage = function (evt) {
                _this.appendMsg(evt.data);
            }
            _this.ws.onclose = function () {
                _this.appendMsg('客户端已断开连接', '#00f');
            }
            _this.ws.onerror = function (evt) {
                _this.appendMsg(evt.data, '#f00');
            }
        },
        close: function () {
            if (this.ws) {
                this.ws.close();
                this.ws = null;
            }
        },
        appendMsg: function (message, color) {
            var li = document.createElement('li');
            li.style.color = color || '#000';
            li.innerHTML = message;
            msg.appendChild(li);
        }
    }
    
    function wsTest() {
        var count = document.getElementById('count').value;
        var url = 'ws://localhost:90/html5/wstask?count=' + count;
        WsUtil.connect(url, function (ws) {
            ws.send('test');
        });
    }
    

    2.ASP.NET MVC后端实现WebSocket请求

    ASP.NET MVC控制器

    public class Html5Controller : Controller
    {
        public void WsTask()
        {
            HttpContext.AcceptWebSocketRequest(ctx =>
            {
                int.TryParse(ctx.QueryString["count"], out int count);
                return WebSocketManager.RunTask(ctx, wsm =>
                {
                    for (int i = 0; i < count; i++)
                    {
                        var message = string.Format("{0:yyyyMMdd HH:mm:ss} 消息{1}", DateTime.Now, i + 1);
                        wsm.SendMessageAsync(message);
                        Thread.Sleep(1000);
                    }
                });
            });
        }
    }
    

    这里封装了一个WebSocket管理者类。

    public class WebSocketManager
    {
        private WebSocket socket;
    
        public WebSocketManager()
        {
        }
    
        public WebSocketManager(WebSocket socket)
        {
            this.socket = socket;
        }
    
        public static async Task RunTask(AspNetWebSocketContext context, Action<WebSocketManager> action)
        {
            var socket = context.WebSocket;
            if (socket.State == WebSocketState.Open)
            {
                var wsm = new WebSocketManager(socket);
                try
                {
                    action(wsm);
                }
                catch (Exception ex)
                {
                    await wsm.SendMessageAsync(ex.Message);
                }
            }
        }
    
        public Task SendMessageAsync(string message)
        {
            var content = new ArraySegment<byte>(Encoding.UTF8.GetBytes(message));
            return socket.SendAsync(content, WebSocketMessageType.Text, true, CancellationToken.None);
        }
    }
    

    3.运行效果

  • 相关阅读:
    一个比喻理解进程和线程的区别
    python蛋疼的编码decode、encode、unicode、str、byte的问题都在这了
    python类中__unicode__和__str__方法的妙用
    python re 正则提取中文
    一个python爬虫协程的写法(gevent模块)
    python 中range和xrange的区别
    python 监控oracle 数据库
    Spring security 知识笔记【自定义登录页面】
    Spring security 知识笔记【内存角色授权】
    Spring security 知识笔记【入门】
  • 原文地址:https://www.cnblogs.com/known/p/8319087.html
Copyright © 2020-2023  润新知