.net core 3.1 创建WebSocket demo

ASP.NET Core Web API的启动类(Startup)

using com.uplus.common;
using com.uplus.log4net;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Management;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Web;
using WebApi.Bill.Biz;
using WebApi.Common;
using WebApi.Models;
using IApplicationLifetime = Microsoft.AspNetCore.Hosting.IApplicationLifetime;

namespace WebApi
{
    /// <summary>
    /// 启动
    /// </summary>
    public class Startup
    {
        public static Dictionary<string, WebSocket> dicWebSocket = new Dictionary<string, WebSocket>();
        public static Dictionary<string, DateTime> dicWebSocketTime = new Dictionary<string, DateTime>();

        private string webRootPath = "";
        public static TcpServerHelper tcpServer = null;

        /// <summary>
        /// ConfigureServices
        /// </summary>
        /// <param name="services"></param>
        public void ConfigureServices(IServiceCollection services)
        {
            Log4Helper.Initializer();
            //Log4Helper.InitailizerConsole();
            services.AddHttpContextAccessor();
            services.AddScoped<LoginInfo>();
            services.AddScoped<HostingEnvironment>();

            services.AddRouting(options => options.LowercaseUrls = true);
            //配置跨域处理,允许所有来源:
            services.AddCors(options =>
            {
                options.AddPolicy("any", builder =>
                {
                    builder.AllowAnyHeader()
                    //.AllowCredentials()//指定处理cookie
                .AllowAnyOrigin(); //允许任何来源的主机访问
                });
            });
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            }).AddCookie(options =>
            {
                options.Cookie.HttpOnly = true;
            });
            //services.AddControllers().AddNewtonsoftJson();
            services.AddDistributedMemoryCache().AddSession(o =>
            {
                o.IdleTimeout = TimeSpan.FromDays(60);
            }).AddMvc(opt =>
            {
                opt.UseCentralRoutePrefix(new RouteAttribute("api/[controller]/[action]"));
            });
            services.AddMvc(option =>
            {
                option.EnableEndpointRouting = false;
            }).SetCompatibilityVersion(CompatibilityVersion.Version_3_0).AddControllersAsServices().AddNewtonsoftJson
            (
                json =>
                {
                    //统一设置JsonResult
                    json.SerializerSettings.ContractResolver = new DefaultContractResolver();
                    json.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";

                    json.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                }
            );
            services
              .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
              .AddJwtBearer(options =>
              {
                  options.TokenValidationParameters = new TokenValidationParameters
                  {
                      ValidIssuer = AppConfigurtaion.GetSecondSection("JwtSetting", "Issuer"),
                      ValidAudience = AppConfigurtaion.GetSecondSection("JwtSetting", "Audience"),
                      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppConfigurtaion.GetSecondSection("JwtSetting", "SecurityKey"))),
                      // 默认允许 300s  的时间偏移量,设置为0
                      ClockSkew = TimeSpan.Zero
                  };
              });
            //解决文件上传Multipart body length limit 134217728 exceeded
            services.Configure<FormOptions>(x =>
            {
                x.ValueLengthLimit = int.MaxValue;
                x.MultipartBodyLengthLimit = int.MaxValue;
                x.MemoryBufferThreshold = int.MaxValue;
            });
            //配置Mvc
            services.AddControllers(options => { options.EnableEndpointRouting = false; });
            services.AddControllers().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
            services.AddControllers().AddNewtonsoftJson();
            services.AddHttpClient();
            ServiceBase.ServiceRegister(services);
        }

        /// <summary>
        /// Configure
        /// </summary>
        /// <param name="app"></param>
        /// <param name="env"></param>
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseStaticFiles();
            app.UseStaticFiles(new StaticFileOptions
            {
                ContentTypeProvider = new FileExtensionContentTypeProvider(new Dictionary<string, string>
                {
                      { ".apk", "application/octet-stream" },
                      { ".zip", "application/octet-stream" }
                })
            });
            app.UseSession();
            app.UseRouting();
            app.UseCors("any");
            app.UseAuthorization();
            app.UseAuthentication();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapControllerRoute(
                       name: "default",
                       pattern: "{controller=Home}/{action=Index}/{id?}");
            });
            app.UseAuthentication();
            app.UseMvc();

            app.UseWebSockets();
            app.Use(async (context, next) =>
            {
                try
                {
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        using (IServiceScope scope = app.ApplicationServices.CreateScope())
                        {
                            WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();

                            if (!dicWebSocket.ContainsKey(GetSessionFlag(context)))
                            {
                                dicWebSocket.Add(GetSessionFlag(context), webSocket);
                            }
                            else
                            {
                                dicWebSocket[GetSessionFlag(context)] = webSocket;
                            }
                            Log4Helper.Info(this.GetType(), $"检测到{GetSessionFlag(context)}连接");
                            await Echo(context, webSocket);
                        }
                    }
                    else
                    {
                        //Hand over to the next middleware
                        await next();
                    }
                }
                catch
                { }
            });
            TaskSchedule();

            webRootPath = ServiceBase.Get<HostingEnvironment>().WebRootPath;
            var provider = new FileExtensionContentTypeProvider();
            provider.Mappings[".log"] = "application/octet-stream";
            app.UseStaticFiles(new StaticFileOptions
            {
                ContentTypeProvider = provider
            });
        }

        #region WebSocket相关

        private async System.Threading.Tasks.Task Echo(HttpContext context, WebSocket webSocket)
        {
            try
            {
                var buffer = new byte[1024 * 4];
                WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                while (!result.CloseStatus.HasValue)
                {
                    string content = Encoding.Default.GetString(new ArraySegment<byte>(buffer, 0, result.Count));
                    //接收的格式(download#20200326251234.jpg,file#20200326251234.jpg|20200326251235.jpg)
                    //要下载文件的数据信息
                    //加入队列
          
                    string data = $"{GetSessionFlag(context)}:{content}";
                    Debug.WriteLine("----------------------------------------");
                    Debug.WriteLine(content);
                    SendMessage("1231", "22");
                    Debug.WriteLine(data);
                    Debug.WriteLine("----------------------------------------");
                    Log4Helper.Info(this.GetType(), $"把数据{data}加入队列");
                    if (content == "ping")
                    {
                        if (!dicWebSocketTime.ContainsKey(GetSessionFlag(context)))
                        {
                            dicWebSocketTime.Add(GetSessionFlag(context), DateTime.Now);
                        }
                        else
                        {
                            dicWebSocketTime[GetSessionFlag(context)] = DateTime.Now;
                        }
                        SendMessage(GetSessionFlag(context), "pang");
                    }
                    if (!string.IsNullOrEmpty(data) && data != "ping")
                    {
                        string[] str = data.Split(':');
                        if (!string.IsNullOrEmpty(str[1]))
                        {
                            //string[] strList = str[1].Split('#');
                            string[] strList = str;
                            switch (strList[1])
                            {
                                case "ping":
                                    TerminalModel model = BizBase.Get<BizTerminal>().Get(strList[0]);
                                    if (model != null)
                                    {
                                        //
                                        DateTime t1 = Convert.ToDateTime(model.TRequest).AddMinutes(2);
                                        DateTime t2 = DateTime.Now;
                                        int compNum = DateTime.Compare(t1, t2);
                                        if (compNum <= 0)
                                        {
                                            model.NTerState = 0;
                                        }
                                        else
                                        {
                                            model.NTerState = 1;
                                        }
                                        model.TRequest = DateTime.Now;
                                        BizBase.Get<BizTerminal>().UpdateModel(model);
                                    }
                                    Log4Helper.Info("获取连接信息", $"设备{str[1]}连接");
                                    //更新相关数据
                                    break;
                            }
                        }
                    }
                    Thread.Sleep(1000);
                    result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                }
                await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
            }
            catch (Exception ex)
            {
                Log4Helper.Error(this.GetType(), "WebSocket相关异常", ex);
            }
        }

        public static void SendMessage(string flag, string message)
        {
            Log4Helper.Info("终端设置", $"对终端{flag},发送命令{message}");
            try
            {
                Log4Helper.Info("连接池", $"当前终端连接设备数量{dicWebSocket.Count}");
                if (dicWebSocket.Count > 0)
                {
                    foreach (string item in dicWebSocket.Keys)
                    {
                        Log4Helper.Info("连接池连接信息", $"当前终端连接设备名称{item}");
                    }
                }
                if (dicWebSocket.ContainsKey(flag))
                {
                    if (dicWebSocket[flag].State == WebSocketState.Open)
                    {
                        dicWebSocket[flag].SendAsync(Encoding.Default.GetBytes(message), WebSocketMessageType.Text, true, CancellationToken.None);
                        Log4Helper.Info("连接池连接信息", $"当前终端连接{flag}开门消息发送成功");
                    }
                    else
                    {
                        dicWebSocket[flag].CloseAsync(WebSocketCloseStatus.NormalClosure, "异常断开", CancellationToken.None);
                        Log4Helper.Info("连接池连接信息", $"当前终端连接{flag}连接已丢失");
                        dicWebSocket.Remove(flag);
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }

        private string GetSessionFlag(HttpContext context)
        {
            if (context != null && context.Request.Path != null)
            {
                return HttpUtility.UrlDecode(context.Request.Path.ToString().TrimStart('/'));
            }
            return "";
        }

        #endregion WebSocket相关

        public void TaskSchedule()
        {
            try
            {
                try
                {
                    string dataPath = $"{ServiceBase.Get<HostingEnvironment>().WebRootPath}\\Config";
                    if (!Directory.Exists(dataPath))
                    {
                        Directory.CreateDirectory(dataPath);
                    }
                    //File.WriteAllText($"{dataPath}\\config.ini", DataConvert.DESEncrypt(MachineInfoHelper.GetCPUSerialNumber(), "12345678"));
                    File.WriteAllText($"{dataPath}\\config.ini", DataConvert.DESEncrypt(GetActiveMacAddress(), "12345678"));
                }
                catch (Exception ex)
                {
                }

                //ChangeToken(1);
            }
            catch (Exception ex)
            {
                Log4Helper.Error(this.GetType(), "TaskSchedule异常", ex);
            }
        }

        #region GetActiveMacAddress 获取网卡地址

        public string GetActiveMacAddress()
        {
            string strCpuID = "";
            ManagementClass mc = new ManagementClass("Win32_Processor");
            ManagementObjectCollection moc = mc.GetInstances();

            foreach (ManagementObject mo in moc)
            {
                strCpuID = mo.Properties["ProcessorId"].Value.ToString().ToLower();
                Log4Helper.Info(this.GetType(), $"CpuID:{strCpuID}");
                break;
            }
            return strCpuID;
        }

        #endregion GetActiveMacAddress 获取网卡地址
    }
}

前端代码(1231作为连接标识存入WebSocket字典绑定WebSocket)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>websocket client</title>
    <script type="text/javascript">
        var start = function () {
            var inc = document.getElementById('incomming');
            var wsImpl = window.WebSocket || window.MozWebSocket;
            var form = document.getElementById('sendForm');
            var input = document.getElementById('sendText');
 
            inc.innerHTML += "connecting to server ..<br/>";
 
            // create a new websocket and connect
            window.ws = new wsImpl('ws://192.168.1.118:5001/1231');
 
            // when data is comming from the server, this metod is called
            ws.onmessage = function (evt) {
                inc.innerHTML += evt.data + '<br/>';
            };
 
            // when the connection is established, this method is called
            ws.onopen = function () {
                inc.innerHTML += '.. connection open<br/>';
            };
 
            // when the connection is closed, this method is called
            ws.onclose = function () {
                inc.innerHTML += '.. connection closed<br/>';
            }
 
            form.addEventListener('submit', function (e) {
                e.preventDefault();
                var val = input.value;
                ws.send(val);
                input.value = "";
            });
 
        }
        window.onload = start;
    </script>
</head>
<body>
    <form id="sendForm">
        <input id="sendText" placeholder="Text to send" />
    </form>
    <pre id="incomming"></pre>
</body>
</html>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: .NET Core 3.1 Web API 项目框架是一个用于构建基于RESTful风格的Web API的开发框架。它是.NET Core平台的一部分,可以运行在多个操作系统上,如Windows、Linux和MacOS。以下是该框架的一些主要特点: 1. 跨平台:.NET Core 3.1 Web API可以在多个操作系统上运行,这为开发人员带来了更大的灵活性和便利性。 2. 高性能:.NET Core是一个高性能的框架,可以处理大量的并发请求。它经过优化,能够提供快速响应时间和较低的资源消耗。 3. 轻量级:相比于传统的.NET框架,.NET Core是一个更轻量级的框架。它采用了模块化体系结构,可以选择性地引用和使用需要的组件,减少了部署包的大小。 4. 开放性:.NET Core 3.1 Web API是一个开放的框架,可以与其他平台和技术进行无缝集成。它支持多种数据格式和协议,如JSON、XML、RESTful和WebSocket等。 5. 高度可扩展:通过使用中间件和自定义管道,开发人员可以方便地扩展和定制Web API的功能。它还支持依赖注入和插件机制,使得代码的组织和测试变得更加简单。 6. 安全性:.NET Core 3.1 Web API提供了强大的安全性功能,包括身份验证、授权、访问控制等。它支持常见的认证方案,如基于令牌的身份验证和OAuth。 总之,.NET Core 3.1 Web API是一个现代化、高效且可扩展的框架,适用于构建各种规模的Web API应用程序。它简化了开发过程,提供了丰富的功能和工具,帮助开发人员快速构建高质量的API。 ### 回答2: .NET Core 3.1 Web API项目框架是用于构建基于RESTful风格的Web服务的开发框架。它是在跨平台、高性能和可扩展性方面进行了优化的框架。 .NET Core 3.1是一个开源的、跨平台的框架,可以在Windows、Linux和Mac等多个操作系统上运行。这意味着我们可以使用相同的代码和工具来构建应用程序,无需为不同的操作系统创建额外的代码。 Web API是一种使用HTTP协议提供数据交互的应用程序编程接口。它通过HTTP请求(通常是GET、POST、PUT、DELETE)来处理数据,并返回JSON或XML等数据格式作为响应。Web API是一种通用的服务架构,可以与不同平台上的客户端应用程序进行通信。 在.NET Core 3.1 Web API项目框架中,我们可以使用C#来编写API控制器,通过定义不同的API端点和路由来处理不同类型的请求。我们可以使用一些常用的属性(如[HttpGet]、[HttpPost]等)来定义API端点,并使用参数绑定来获取请求中的数据。 框架还提供了丰富的中间件和插件,以处理身份验证、授权、日志记录等常见的开发需求。我们还可以通过使用依赖注入来管理应用程序中的组件和服务。 另外,.NET Core 3.1框架还提供了一些实用的工具和库,例如Entity Framework Core、Swagger等,可以简化数据库访问和API文档生成等任务。 总之,.NET Core 3.1 Web API项目框架是一个强大、灵活和高效的开发框架,可以帮助我们构建出高性能和可靠的Web服务。它具有跨平台的优势,并提供了丰富的功能和工具来简化开发流程。 ### 回答3: .NET Core 3.1是一个跨平台的开发框架,适用于构建不同类型应用的云和互联网解决方案。在.NET Core 3.1中,WebAPI项目框架也得到了重要的改进和功能增强。 首先,.NET Core 3.1的WebAPI项目框架提供了更强大的路由功能,可以使用属性路由来定义API的访问路径,从而更灵活地组织和管理API的接入点。 其次,.NET Core 3.1的WebAPI项目框架引入了端点路由的概念,可以根据不同的HTTP方法和路由规则来映射到不同的动作方法,从而实现更细粒度的控制。 此外,.NET Core 3.1的WebAPI项目框架还提供了更强大的模型绑定功能,可以将请求的数据自动绑定到动作方法的参数上,大大减少了编写冗余代码的工作量。 在数据序列化方面,.NET Core 3.1的WebAPI项目框架支持多种数据格式,包括JSON和XML,可以根据客户端的需求选择合适的数据格式进行传输。 此外,.NET Core 3.1的WebAPI项目框架还提供了强大的中间件支持,可以实现各种功能,如身份验证、授权、异常处理等,极大地提高了开发效率。 总体来说,.NET Core 3.1的WebAPI项目框架在路由、模型绑定、数据序列化和中间件方面都得到了重要的改进和增强,为开发者提供了更强大、更灵活的开发工具,使得构建高性能、可扩展的WebAPI应用变得更加简单和方便。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚构的乌托邦

如果可以请打赏鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值