2023. 6. 26. 00:00ㆍASPNET/SignalR
signalR core 는 dotnet core 에서 실시간 통신을 위해 내놓은 비동기 양방향 통신 frameworks 이다.
aspnet core 위에서 돌아가는 형태 이다.
https://yogingang.tistory.com/404
Rest API Template 만들기 - EP 01 (Create , Swagger, Logging)
Create visual studio 2022 를 실행하고 Create a new project 를 선택한다. asp.net core web api 선택 Project name 정하기 Additional Information 설정 Create 하면 Project 가 생성된다. F5 를 누르면 실행 된다. 위와 같이 swagger
yogingang.tistory.com
위 강좌를 보고 간단한 rest api 를 만들고 추가 할 수도 있다. 참고 바란다.
어쨌든 rest api 또는 blazor, mvc 등을 이용하여 간단한 project 를 생성 했다고 가정 하자.
signalR core 는 dotnet core 에 포함되어 있으니 따로 설치를 할 필요는 없다. (aspnet core 7 기준)
이제 아주 간단한 Push server 를 구현해보자
createChannel 을 이용해 channel 을 생성하고
해당 channel 에 join 한 client 들에 message 를 전달할 것이다.
signalR 에서 method 를 구현 하려면 Hub 를 상속하여야 한다.
ChannelHub.cs
public class ChannelHub : Hub
{
private readonly ILogger<ChannelHub> _logger;
public ChannelHub(ILogger<ChannelHub> logger)
{
_logger = logger;
}
[HubMethodName("sendMessage")]
public async Task SendMessage(string channelId, string message)
{
_logger.LogInformation($"{Context.User}");
await Clients.OthersInGroup(channelId).SendAsync("receiveMessage",message);
}
// 하나는 channel 을 관리하기 위한 group
// 다른 하나는 client 를 관리하기 위한 group
[HubMethodName("create")]
public async Task<Create.Response> CreateChannel()
{
var channelId = Guid.NewGuid().ToAlphaNumeric();
var joinId = Guid.NewGuid().ToAlphaNumeric();
await Groups.AddToGroupAsync(Context.ConnectionId, channelId);
await Groups.AddToGroupAsync(Context.ConnectionId, joinId);
return new Create.Response { ChannelId = channelId, JoinId = joinId };
}
// 하나는 channel 을 관리하기 위한 group
// 다른 하나는 client 를 관리하기 위한 group
[HubMethodName("join")]
public async Task<Join.Response> JoinChannel(string channelId)
{
var joinId = Guid.NewGuid().ToAlphaNumeric();
await Groups.AddToGroupAsync(Context.ConnectionId, channelId);
await Groups.AddToGroupAsync(Context.ConnectionId, joinId);
return new Join.Response { JoinId =joinId };
}
[HubMethodName("left")]
public async Task LeftChannel(string channelId, string joinId)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, channelId);
await Groups.RemoveFromGroupAsync(Context.ConnectionId, joinId);
}
}
Groups.AddToGroupAsync 를 이용해 client 를 등록한다.
위에서 두번 등록 하는 이유는 하나는 channel 을 통해 send한 caller 를 제외하고 모든 group member 들에게 message 를 전달하기 위한 것이고 다른 하나는 joinId 를 통해 직접 한 사람에게 message 를 전달하기 위해서 이다.
Response class
public class Create
{
public class Response
{
public string ChannelId { get; set; } = string.Empty;
public string JoinId { get; set; } = string.Empty;
}
}
public class Join
{
public class Response
{
public string JoinId { get; set; } = string.Empty;
}
}
Program.cs
...
app.MapHub<ChannelHub>("/channel", options=>
{
options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
});
...
이렇게 하면 server 는 준비가 된 것이다.
이제 위에 접속하기 위해 console project 를 아무거나 하나 만들자
그리고 nuget 에서 다음 package 를 추가 하자
dotnet add package Microsoft.AspNetCore.SignalR.Client
Program.cs
// See https://aka.ms/new-console-template for more information
using Microsoft.AspNetCore.SignalR.Client;
Console.WriteLine("Hello, World!");
HubConnection InitSignalRClient()
{
// signalR 접속 url
var url = $"https://localhost:5004/channel";
var connection = new HubConnectionBuilder()
.WithUrl(url, options =>
{
options.SkipNegotiation = true;
options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
})
.WithAutomaticReconnect()
.Build();
return connection;
}
// connection1 생성
var connection1 = InitSignalRClient();
// server 접속
await connection1.StartAsync();
// server 의 create method 를 이용해 channel create
// channelId 및 joinId 를 return 한다.
var createResponse = await connection1.InvokeAsync<Create.Response>("create");
// receiveMessage 를 method 로 정의 하여 server 로 부터 message 를 전달 받을 수 있도록 대기 한다.
connection1.On<string>("receiveMessage", message => Console.WriteLine($"connection1 received : {message}"));
var connection2 = InitSignalRClient();
await connection2.StartAsync();
// connection2 는 channel 에 join 하고 joinId 를 reutrn 받는다.
var joinResponse = await connection2.InvokeAsync<Join.Response>("join", createResponse.ChannelId);
// receiveMessage 를 method 로 정의 하여 server 로 부터 message 를 전달 받을 수 있도록 대기 한다.
connection2.On<string>("receiveMessage", message => Console.WriteLine($"connection2 received : {message}"));
// connection 1 로 message 전달
await connection2.SendAsync("sendMessage", createResponse.ChannelId, "hello im connection2");
// connection 2 로 message 전달
await connection1.SendAsync("sendMessage", createResponse.ChannelId, "hello im connection1");
Console.ReadLine();
이제 server 를 실행하고 client 를 실행하면 connection1 과 connection2 가 data 를 주고 받는걸 확인 할 수 있을 것이다.
console 을 여러게 만들고 connection 을 하나씩만 유지 하여 test 해봐도 된다.
관련영상
'ASPNET > SignalR' 카테고리의 다른 글
ASPNET Core SignalR 을 이용한 Push Server 구현 - 2 (인증처리) (0) | 2023.07.03 |
---|