.NetCore 2.2 ปัญหา SignalR

Sep 17 2020

ฉันมีปัญหาบางอย่างกับโปรเจ็กต์ที่พยายามใช้ SignalR เพื่อเรียกใช้คำขออ่านแหล่งข้อมูลไปยังไคลเอนต์ที่เชื่อมต่อทั้งหมดสำหรับการรีเฟรชข้อมูลกริดเพื่อให้ผู้ใช้เห็นการอัปเดตแบบเรียลไทม์

สิ่งนี้ใช้งานได้ใน IIS Express ในขณะที่ทำงานใน Visual Studio โดยใช้หน้าต่างโครเมียมสองหน้าต่าง SignalR เชื่อมต่อทั้งในหน้าต่างและเรียกใช้การดำเนินการอ่านแหล่งข้อมูลโดยไม่มีข้อผิดพลาดเมื่อแก้ไขในหน้าต่างเบราว์เซอร์ใด ๆ

เมื่อปรับใช้กับเซิร์ฟเวอร์ที่เรียกใช้ IIS 10.0.17763.1 ข้อผิดพลาดจะปรากฏขึ้น

แอปพลิเคชันโฮสต์อยู่บนเซิร์ฟเวอร์เดียวและหากหน้าต่างเบราว์เซอร์เปิดอยู่การเชื่อมต่อกับ SignalR จะทำงานได้ (ฉันได้รับบันทึกคอนโซลของการเชื่อมต่อจากการเชื่อมต่อรอการโทรเริ่มต้น) แต่เมื่อเปิดหรือเปิดหน้าต่างเบราว์เซอร์ที่สองบนเครื่องอื่นความล้มเหลวหลายอย่างของ SingalR จะเริ่มปรากฏในคอนโซลสำหรับแต่ละอินสแตนซ์ของเบราว์เซอร์

ข้อผิดพลาดมีดังนี้:

เครื่องเบราว์เซอร์ 1:

    https://FQDN:2424/trafficWorkflowHub?id=YPCykB9G94tbgzlnZZDi5g 404 (Not Found) 
    Error: Server returned handshake error: An unexpected error occurred during connection handshake. 
    InvalidDataException: Missing required property 'protocol'. Message content: {"arguments": 
   [],"invocationId":"1","target":"UpdateDataSource","type":1} 
    TrafficWorkflow:181 Error: Not Found
        at new HttpError (signalr.js:1487)
        at XMLHttpRequest.xhr.onload (signalr.js:1777)
    TrafficWorkflow:182 connected

เครื่องเบราว์เซอร์ 2:

 signalr.js:3927 WebSocket connection to 'wss://FQDN:2424/trafficWorkflowHub?id=2sW4zudCQKoysUQB9mB1vQ' 
failed: Error during WebSocket handshake: Unexpected response code: 404
signalr.js:2684 [2020-09-17T10:57:34.529Z] Information: SSE connected to 
https://FQDN:2424/trafficWorkflowHub?id=E9M_Wkbpt1KBPcHxLHhJXA
signalr.js:1788 POST https://FQDN:2424/trafficWorkflowHub?id=E9M_Wkbpt1KBPcHxLHhJXA 404 (Not Found)
signalr.js:2678 [2020-09-17T10:57:34.060Z] Error: Failed to start the transport 'WebSockets': null

ตัวอย่างโค้ดอยู่ด้านล่าง

รหัสฝั่งไคลเอ็นต์:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/trafficWorkflowHub")
    .build();

async function start() {
    try {
        await connection.start().catch(err => console.error(err));
        console.log("connected");
    } catch (err) {
        console.log(err);
        setTimeout(() => start(), 5000);
    }
}

connection.onclose(async () => {
    await start();
});


connection.on("ReceiveUpdates", function () {
    callDataSourceRead();
});

start() อยู่ในส่วนเอกสารพร้อม

เรียกใช้การเรียกเพื่ออัปเดตแหล่งข้อมูลในเพจ cshtml ด้วยการเรียกนี้:

 connection.invoke("UpdateDataSource").catch(function (err) {
                    return console.error(err.toString());
                });

รหัสฝั่งเซิร์ฟเวอร์มีดังนี้:

  public class TrafficWorkflowHub : Hub
    {

        public async Task UpdateDataSource()
        {
            await Clients.All.SendAsync("ReceiveUpdates");
        }

    }

ใน Startup.cs โมฆะสาธารณะกำหนดค่า

app.UseSignalR(routes =>
            {
                routes.MapHub<TrafficWorkflowHub>("/trafficWorkflowHub");
           
            });

โมฆะสาธารณะ ConfigureServices

  services.AddSignalR(hubOptions =>
            {
                hubOptions.EnableDetailedErrors = true;
            });

คำตอบ

Kiril1512 Sep 17 2020 at 20:04

ตรวจสอบให้แน่ใจว่าคุณกำหนดค่า CORS เช่นนี้ (คำสั่งมีความสำคัญ):

services.AddCors(options =>
{
    options.AddPolicy(CorsPolicy, builder => builder.WithOrigins("https://yourFrameworkApp.azurewebsites.com")
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials()
        .SetIsOriginAllowed((host) => true));
});

จากนั้นตรวจสอบให้แน่ใจว่าคุณมีสิ่งเหล่านี้ในวิธีการกำหนดค่าเมื่อเริ่มต้น:

app.UseHttpsRedirection();
app.UseWebSockets();

และอย่าลืมเปิดใช้งาน websockets บนเซิร์ฟเวอร์: