跳至主要內容

3.3 WebSocket

linguicheng...大约 2 分钟

简介

Wing的服务网关支持WebSocket请求的转发,同时支持Wing服务的所有负载均衡算法。

状态码说明

  • 1001 找不到下游服务

  • 1008 权限认证不通过

  • 1011 网关或服务异常

创建一个支持WebSocket的网关

安装依赖包

dotnet add package Wing.Consul

dotnet add package Wing.Gateway

Program代码

using Wing;

var builder = WebApplication.CreateBuilder(args);

builder.Host.AddWing(builder => builder.AddConsul());

builder.Services.AddWing()
                    .AddJwt()
                    .AddPersistence()
                    .AddGateWay(new WebSocketOptions
                    {
                        KeepAliveInterval = TimeSpan.FromMinutes(2)
                    });

var app = builder.Build();
app.Run();

配置示例

支持JWT认证和固定的"Key"认证
UseJWTAuth 是否启用JWT认证,请求示例ws://localhost:3311/Wing.Demo_3.3/ws?token=abc
AuthKey 固定的"Key"认证,请求示例ws://localhost:3311/Wing.Demo_3.3/ws?key=abc

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  // 是否启用配置中心,默认启用
  "ConfigCenterEnabled": false,
  "Consul": {
    "Url": "http://localhost:8500",
    "Service": {
      //Http  Grpc
      "Option": "Http",
      "HealthCheck": {
        //单位:秒
        "Timeout": 10,
        //单位:秒
        "Interval": 10
      },
      "Name": "Wing.Demo_3.3.1",
      "Host": "localhost",
      "Port": 3311,
      "Tag": "测试",
      "LoadBalancer": {
        //RoundRobin  WeightRoundRobin LeastConnection
        "Option": "WeightRoundRobin",
        //权重
        "Weight": 50
      },
      "Scheme": "https"
    },
    //定时同步数据时间间隔,单位:秒 小于等于0表示立即响应
    "Interval": 10
  },
  "Jwt": {
    "Secret": "U2FsdGVkX18E82bSYRnqfv7isu6313BQ8QNTs0TcZZK2rwviQw==",
    "Iss": "https://gitee.com/linguicheng/Wing",
    "Aud": "Wing",
    //token过期分钟数
    "Expire": 1440
  },
  //自动同步实体结构到数据库
  "UseAutoSyncStructure": true,
  "ConnectionStrings": {
    "Wing": "Data Source=192.168.56.96;Initial Catalog=Wing;User ID=sa;Password=wing123.;MultipleActiveResultSets=true"
  },
  "Gateway": {
    "Policy": {
      //  // 全局策略
      "Global": {
        "UseJWTAuth": false
        //"AuthKey": "abc"
      }
    },
    // 请求日志
    "Log": {
      "IsEnabled": true,
      "UseEventBus": false
    }
  }
}

创建一个WebSocket服务

安装依赖包

dotnet add package Wing.Consul

Program代码

using System.Net.WebSockets;
using Wing;

var builder = WebApplication.CreateBuilder(args);

builder.Host.AddWing(builder => builder.AddConsul());

builder.Services.AddWing();

var app = builder.Build();

var webSocketOptions = new WebSocketOptions
{
    KeepAliveInterval = TimeSpan.FromMinutes(2)
};

app.UseWebSockets(webSocketOptions);

app.UseDefaultFiles();
app.UseStaticFiles();

app.Use(async (context, next) =>
{
    if (context.Request.Path == "/ws")
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
            await Echo(webSocket);
        }
        else
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
        }
    }
    else
    {
        await next(context);
    }

});


app.Run();

async Task Echo(WebSocket webSocket)
{
    var buffer = new byte[1024 * 4];
    var receiveResult = await webSocket.ReceiveAsync(
        new ArraySegment<byte>(buffer), CancellationToken.None);

    while (!receiveResult.CloseStatus.HasValue)
    {
        await webSocket.SendAsync(
            new ArraySegment<byte>(buffer, 0, receiveResult.Count),
            receiveResult.MessageType,
            receiveResult.EndOfMessage,
            CancellationToken.None);

        receiveResult = await webSocket.ReceiveAsync(
            new ArraySegment<byte>(buffer), CancellationToken.None);
    }

    await webSocket.CloseAsync(
        receiveResult.CloseStatus.Value,
        receiveResult.CloseStatusDescription,
        CancellationToken.None);
}

查看运行结果

启动网关示例3.3-1,启动WebSocket服务实例3.3,点击“Connect”按钮连接WebSocket服务端,在文本框输入要发送的内容,WebSocket服务端会一样返回该内容,如下图:

上次编辑于:
贡献者: linguicheng