안녕하세요! C#을 열심히 공부하고 있는 초보입니다…ㅎㅎ
이번 .NET 8에서 사용할 수 있게된 InteractiveAuto 모드에 대해 공부하며 테스트해보고 있는데요,
질문드리고싶은 부분이 생겨 작성하게 되었습니다!
Auto 모드는 페이지 첫 로드(방문)시에 InteractiveServer 모드로 동작하고 이후 재방문 시에는 InteractiveWebAssembly 모드로 동작하는 방식이라고 알고있는데
Server 모드로 동작을 하는지, WebAssembly 모드로 동작하는지 확인할 방법이 있나요?
지금은 Console.WirteLine 코드를 추가해서 콘솔 메시지가 서버 콘솔 창에 출력되는지, 브라우저의 콘솔 창에 출력되는지로 확인하고 있는데 이렇게 확인하는 방법이 맞는 방법인지, 다른 방법이 있다면 어떻게 확인할 수 있는지 궁금합니다!
1번의 콘솔 메시지 방법으로 출력 위치로 확인했을 때 Auto 모드의 페이지가 Server 동작 → WebAssembly로 클라이언트에서 동작하도록 스위치되는 조건이 단순히 재방문할 때가 아니라 WebSocket 연결이 되어있는지의 여부인 것 같더라구요…!
(WebSocket 연결 여부는 브라우저 콘솔 창의 connect 메시지로 확인했습니다)
(아래 서버에서 실행/클라이언트에서 실행이라는 말은 콘솔 메시지가 어디에서 출력되는지를 보고 작성했습니다 이 방법이 실행되는 위치를 판단하는 데에 잘못된 방법이라면 알려주시면 감사하겠습니다!)
예를 들어 첫 페이지가 Static Server 모드로 실행됐으면 연결된 WebSocket이 없음 → Interactive Auto모드 페이지로 진입하면 바로 클라이언트에서 실행
첫 페이지가 Interactive Server 모드면 연결된 WebSocket이 있음 → Auto 페이지에 진입하면 서버에서 실행
이후 Server 모드 페이지와 Auto모드 페이지를 왔다갔다 이동하면 재방문 시에도 계속 서버에서 동작하다가 WebAssembly 모드의 페이지나 Static Server 모드의 페이지 방문으로 WebSocket 연결이 끊어지면 Auto 모드의 페이지 방문시 클라이언트에서 동작, 다시 Server 모드 페이지 방문으로 WebSocket 연결이 생기면 Auto 모드 페이지 재방문시 클라이언트가 아닌 서버에서 동작
설명이 너무 간결하지 못하네요 죄송합니다…ㅠ-ㅠ Auto 모드의 설명만 봤을때는 첫 방문: 서버 동작, 이후 재방문: 쭉 클라이언트 동작으로 예상했는데 제가 테스트해본 방식이 잘못됐을까요?
답변 주셔서 정말 감사드립니다! 콘솔 출력 위치가 달라지는걸 확실히 알고 넘어갈 수 있게 되었어요 알려주셔서 감사드려요 !!
Auto 모드가 공식 문서를 보면서 이해했던 개념+기대했던 동작이랑 테스트하며 확인하는 동작이랑 달라서 조금 어렵네요ㅠ.ㅠ Prerendering Webassembly Mode처럼 동작한다는 말씀이 맞는 것 같아요
혹시 Console.WriteLine(RuntimeInformation.OSDescription);로 출력했을 때 Browser/Window 버전으로 각각 나누어 출력이 되는데 이렇게 확인할 수도 있다고도 볼 수 있을까요?
프레임워크 별로 실행 환경을 알려주는 클래스가 있기는 한데, 범용으로 쓰기에는 무리가 있습니다.
예를 들면, IJSInProcessRuntime 은 블레이저 와즘에만 존재하는 서비스입니다.
이 서비스의 주입을 요청받을 때 에러가 나지 않으면 Wasm 이라고 볼 수 있는 것이죠.
블레이저는 호스팅 모델에 기반하고 있어, 호스트가 제공하는 서비스 컨테이너를 이용하면 좀 더 범용적인 방식을 도입할 수 있습니다.
interface IBlazorHost
{
string Name {get; }
}
class ServerHost : IBlazorHost
{
public string Name { get; } = "Server";
}
class WasmHost : IBlazorHost
{
public string Name { get; } = "Wasm";
}
class MauiHost : IBlazorHost
{
public string Name { get; } = "Maui";
}
자세한 답변 정말정말 감사드립니다!! 저에게 너무 필요했던 답변입니다
그런데 혹시 제가 어떤 부분을 실수한건지 클라이언트 프로젝트의 Program.cs 파일에 올려주신 코드로 서비스 등록을 하였는데도 등록된 서비스를 찾을 수 없다는 오류가 발생합니다 서버 프로젝트의 Program.cs에 등록한 서비스는 잘 인식하는데 무엇을 놓친걸까요?
서버 프로젝트와 클라이언트 프로젝트에 모두 IBlazorHost 인터페이스 클래스를 만들고 양쪽 Program.cs에 모두 서비스를 등록했는데 클라이언트 쪽 서비스만 찾을 수 없다는 에러가 출력됩니다ㅠ.ㅠ
이 객체는 모든 프로젝트에서 참조하기 때문에 별도의 클래스 라이브러리 프로젝트에 정의하는게 좋습니다.
예를 들면, CommonServices 라는 이름으로 클래스 라이브러리 프로젝트를 추가하고 거기에, IBlazorhost 를 정의합니다.
// CommonServices.IBlazorHost.cs
namespace CommonServices;
public interface IBlazorHost
{
string Name {get; }
}
public class ServerHost : IBlazorHost
{
public string Name { get; } = "Server";
}
public class WasmHost : IBlazorHost
{
public string Name { get; } = "Wasm";
}
public class MauiHost : IBlazorHost
{
public string Name { get; } = "Maui";
}
각각의 구현 클래스를 각 프로젝트에 분산시킬 수도 있는데, 위의 코드는 클래스 라이브러리에 기본 구현체들을 넣어 둔 것입니다.
서버 프로젝트와 클라이언트 프로젝트는 이 프로젝트를 참조하여, IBlazorHost를 공통적으로 사용하면 됩니다.