SignalR 문제 해결(SignalR 1.x)

작성자 : Patrick Fletcher

경고

이 설명서는 최신 버전의 SignalR용이 아닙니다. ASP.NET Core SignalR을 살펴보세요.

이 문서에서는 SignalR의 일반적인 문제 해결 문제를 설명합니다.

이 문서에는 다음 섹션이 포함되어 있습니다.

클라이언트와 서버 간의 호출 메서드가 자동으로 실패함

이 섹션에서는 의미 있는 오류 메시지 없이 클라이언트와 서버 간의 메서드 호출이 실패할 수 있는 원인에 대해 설명합니다. SignalR 애플리케이션에서 서버에는 클라이언트가 구현하는 메서드에 대한 정보가 없습니다. 서버가 클라이언트 메서드를 호출하면 메서드 이름 및 매개 변수 데이터가 클라이언트로 전송되고 서버가 지정한 형식으로 있는 경우에만 메서드가 실행됩니다. 클라이언트에서 일치하는 메서드를 찾을 수 없는 경우 아무 작업도 수행되지 않으며 서버에서 오류 메시지가 발생하지 않습니다.

호출되지 않는 클라이언트 메서드를 자세히 조사하려면 허브에서 시작 메서드를 호출하기 전에 로깅을 켜서 서버에서 들어오는 호출을 확인할 수 있습니다. JavaScript 애플리케이션에서 로깅을 사용하도록 설정하려면 클라이언트 쪽 로깅을 사용하도록 설정하는 방법(JavaScript 클라이언트 버전)을 참조하세요. .NET 클라이언트 애플리케이션에서 로깅을 사용하도록 설정하려면 클라이언트 쪽 로깅을 사용하도록 설정하는 방법(.NET 클라이언트 버전)을 참조하세요.

맞춤법이 틀린 메서드, 잘못된 메서드 서명 또는 잘못된 허브 이름

호출된 메서드의 이름 또는 서명이 클라이언트의 적절한 메서드와 정확히 일치하지 않으면 호출이 실패합니다. 서버에서 호출하는 메서드 이름이 클라이언트의 메서드 이름과 일치하는지 확인합니다. 또한 SignalR은 JavaScript에서와 같이 카멜식 대/소문자 메서드를 사용하여 허브 프록시를 만들므로 서버에서 호출 SendMessage 된 메서드가 클라이언트 프록시에서 호출 sendMessage 됩니다. 서버 쪽 코드에서 특성을 사용하는 HubName 경우 사용된 이름이 클라이언트에서 허브를 만드는 데 사용된 이름과 일치하는지 확인합니다. 특성을 사용하지 HubName 않는 경우 JavaScript 클라이언트의 허브 이름이 ChatHub 대신 chatHub와 같이 카멜식 대/소문자인지 확인합니다.

클라이언트의 중복 메서드 이름

대/소문자만 다른 중복 메서드가 클라이언트에 없는지 확인합니다. 클라이언트 애플리케이션에 라는 메서드가 있는 경우 라는 sendMessageSendMessage 메서드도 없는지 확인합니다.

클라이언트에 JSON 파서 누락

SignalR은 서버와 클라이언트 간의 호출을 직렬화하기 위해 JSON 파서가 있어야 합니다. 클라이언트에 기본 제공 JSON 파서(예: 인터넷 Explorer 7)가 없는 경우 애플리케이션에 하나를 포함해야 합니다. 여기에서 JSON 파서 를 다운로드할 수 있습니다.

Hub 및 PersistentConnection 구문 혼합

SignalR은 허브 및 PersistentConnections라는 두 가지 통신 모델을 사용합니다. 이러한 두 통신 모델을 호출하는 구문은 클라이언트 코드에서 다릅니다. 서버 코드에 허브를 추가한 경우 모든 클라이언트 코드가 적절한 허브 구문을 사용하는지 확인합니다.

JavaScript 클라이언트에서 PersistentConnection을 만드는 JavaScript 클라이언트 코드

var myConnection = $.connection('/echo');

Javascript 클라이언트에서 허브 프록시를 만드는 JavaScript 클라이언트 코드

var myHub = $.connection.MyHub;

경로를 PersistentConnection에 매핑하는 C# 서버 코드

RouteTable.Routes.MapConnection<MyConnection>("my", "/echo");

여러 애플리케이션이 있는 경우 허브 또는 여러 허브에 경로를 매핑하는 C# 서버 코드

RouteTable.Routes.MapHubs();

구독이 추가되기 전에 연결이 시작됨

서버에서 호출할 수 있는 메서드가 프록시에 추가되기 전에 허브의 연결이 시작되면 메시지가 수신되지 않습니다. 다음 JavaScript 코드는 허브를 제대로 시작하지 않습니다.

허브 메시지를 수신할 수 없는 잘못된 JavaScript 클라이언트 코드

var chat = $.connection.chatHub;
$.connection.hub.start().done(function () {
    chat.client.broadcastMessage = function (name, message) {...};
});

대신 시작을 호출하기 전에 메서드 구독을 추가합니다.

허브에 구독을 올바르게 추가하는 JavaScript 클라이언트 코드

var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {...};
    $.connection.hub.start().done(function () {
        ...
    });

허브 프록시에 메서드 이름이 없습니다.

서버에 정의된 메서드가 클라이언트에서 구독되었는지 확인합니다. 서버에서 메서드를 정의하더라도 클라이언트 프록시에 추가해야 합니다. 메서드는 다음과 같은 방법으로 클라이언트 프록시에 추가할 수 있습니다(메서드는 허브가 아닌 허브의 멤버에 직접 추가 client 됨).

허브 프록시에 메서드를 추가하는 JavaScript 클라이언트 코드

// Method added to proxy in JavaScript:
myHubProxy.server.method1 = function (param1, param2) {...};
//Multiple methods added to proxy in JavaScript using jQuery:
$.extend(myHubProxy.server, {
    method1: function (param1, param2) {...},
    method2: function (param3, param4) {...}
});

공용으로 선언되지 않은 허브 또는 허브 메서드

클라이언트에 표시되려면 허브 구현 및 메서드를 로 public선언해야 합니다.

다른 애플리케이션에서 허브에 액세스

SignalR Hubs는 SignalR 클라이언트를 구현하는 애플리케이션을 통해서만 액세스할 수 있습니다. SignalR은 다른 통신 라이브러리(예: SOAP 또는 WCF 웹 서비스)와 상호 운용할 수 없습니다. 대상 플랫폼에 사용할 수 있는 SignalR 클라이언트가 없는 경우 서버의 엔드포인트에 직접 액세스할 수 없습니다.

수동으로 데이터 직렬화

SignalR은 JSON을 자동으로 사용하여 메서드 매개 변수를 직렬화합니다. 직접 수행할 필요가 없습니다.

OnDisconnected 함수의 클라이언트에서 원격 허브 메서드가 실행되지 않음

이 동작은 의도된 것입니다. OnDisconnected 가 호출되면 허브가 이미 상태에 들어갔 Disconnected 으므로 추가 허브 메서드를 호출할 수 없습니다.

OnDisconnected 이벤트에서 코드를 올바르게 실행하는 C# 서버 코드

public class MyHub : Hub
{
    public override Task OnDisconnected()
    {
        // Do what you want here
        return base.OnDisconnected();
    }
}

연결 제한에 도달했습니다.

Windows 7과 같은 클라이언트 운영 체제에서 IIS의 전체 버전을 사용하는 경우 10개의 연결 제한이 적용됩니다. 클라이언트 OS를 사용하는 경우 대신 IIS Express 사용하여 이 제한을 방지합니다.

도메인 간 연결이 제대로 설정되지 않음

도메인 간 연결(SignalR URL이 호스팅 페이지와 동일한 도메인에 있지 않은 연결)이 올바르게 설정되지 않은 경우 오류 메시지 없이 연결이 실패할 수 있습니다. 도메인 간 통신을 사용하도록 설정하는 방법에 대한 자세한 내용은 도메인 간 연결을 설정하는 방법을 참조하세요.

.NET 클라이언트에서 작동하지 않는 NTLM(Active Directory)을 사용한 연결

연결이 제대로 구성되지 않은 경우 도메인 보안을 사용하는 .NET 클라이언트 애플리케이션의 연결이 실패할 수 있습니다. 도메인 환경에서 SignalR을 사용하려면 다음과 같이 필수 연결 속성을 설정합니다.

연결 자격 증명을 구현하는 C# 클라이언트 코드

connection.Credentials = CredentialCache.DefaultCredentials;

기타 연결 문제

이 섹션에서는 연결 중에 발생하는 특정 증상 또는 오류 메시지의 원인과 해결에 대해 설명합니다.

"데이터를 전송하려면 먼저 시작을 호출해야 합니다." 오류

이 오류는 연결이 시작되기 전에 코드가 SignalR 개체를 참조하는 경우에 일반적으로 표시됩니다. 연결이 완료된 후 서버에 정의된 메서드를 호출하는 처리기 등에 대한 와이어업을 추가해야 합니다. 에 대한 Start 호출은 비동기이므로 호출 후 코드가 완료되기 전에 실행될 수 있습니다. 연결이 완전히 시작된 후 처리기를 추가하는 가장 좋은 방법은 시작 메서드에 매개 변수로 전달되는 콜백 함수에 배치하는 것입니다.

SignalR 개체를 참조하는 이벤트 처리기를 올바르게 추가하는 JavaScript 클라이언트 코드

$.connection.hub.start().done(function () {
    // Wire up Send button to call NewContosoChatMessage on the server.
    $('#newContosoChatMessage').click(function () {
        contosoChatHubProxy.server.newContosoChatMessage(
            $('#displayname').val(), $('#message').val());
            $('#message').val('').focus();
    });

SignalR 개체가 여전히 참조되는 동안 연결이 중지되는 경우에도 이 오류가 표시됩니다.

"301 영구적으로 이동" 또는 "302 임시로 이동" 오류

프로젝트에 SignalR이라는 폴더가 포함되어 있어 자동으로 생성된 프록시를 방해하는 경우 이 오류가 표시될 수 있습니다. 이 오류를 방지하려면 애플리케이션에서 라는 SignalR 폴더를 사용하거나 자동 프록시 생성을 해제하지 마세요. 자세한 내용은 생성된 프록시 및 해당 프록시가 수행하는 작업을 참조하세요 .

.NET 또는 Silverlight 클라이언트의 "403 사용할 수 없음" 오류

이 오류는 도메인 간 통신이 제대로 활성화되지 않은 도메인 간 환경에서 발생할 수 있습니다. 도메인 간 통신을 사용하도록 설정하는 방법에 대한 자세한 내용은 도메인 간 연결을 설정하는 방법을 참조하세요. Silverlight 클라이언트에서 도메인 간 연결을 설정하려면 Silverlight 클라이언트에서 도메인 간 연결을 참조하세요.

"404 찾을 수 없음" 오류

이 문제에는 몇 가지 원인이 있습니다. 다음을 모두 확인합니다.

  • 허브 프록시 주소 참조의 형식이 올바르게 지정되지 않았습니다 . 이 오류는 생성된 허브 프록시 주소에 대한 참조 형식이 올바르게 지정되지 않은 경우에 일반적으로 표시됩니다. 허브 주소에 대한 참조가 제대로 만들어졌는지 확인합니다. 자세한 내용은 동적으로 생성된 프록시를 참조하는 방법을 참조하세요.
  • 허브 경로를 추가하기 전에 애플리케이션에 경로 추가: 애플리케이션에서 다른 경로를 사용하는 경우 추가된 첫 번째 경로가 에 대한 호출 MapHubs인지 확인합니다.

"500 내부 서버 오류"

이것은 다양한 원인이 있을 수 있는 매우 일반적인 오류입니다. 오류의 세부 정보는 서버의 이벤트 로그에 표시되거나 서버 디버깅을 통해 찾을 수 있습니다. 자세한 오류 정보는 서버에서 자세한 오류를 켜서 가져올 수 있습니다. 자세한 내용은 Hub 클래스에서 오류를 처리하는 방법을 참조하세요.

"TypeError: <hubType> 이 정의되지 않았습니다." 오류

이 오류는 에 MapHubs 대한 호출이 제대로 수행되지 않으면 발생합니다. 자세한 내용은 SignalR 경로를 등록하고 SignalR 옵션을 구성하는 방법을 참조하세요.

JsonSerializationException이 사용자 코드에 의해 처리되지 않았습니다.

메서드에 보내는 매개 변수에 직렬화할 수 없는 형식(예: 파일 핸들 또는 데이터베이스 연결)이 포함되어 있지 않은지 확인합니다. 클라이언트로 보내지 않으려는 서버 쪽 개체에서 멤버를 사용해야 하는 경우(보안 또는 직렬화 이유로) 특성을 사용합니다 JSONIgnore .

"프로토콜 오류: 알 수 없는 전송" 오류

이 오류는 클라이언트가 SignalR에서 사용하는 전송을 지원하지 않는 경우에 발생할 수 있습니다. SignalR에서 사용할 수 있는 브라우저에 대한 자세한 내용은 전송 및 대체 를 참조하세요.

"JavaScript Hub 프록시 생성이 사용하지 않도록 설정되었습니다."

이 오류는 에서 동적으로 생성된 프록시signalr/hubs에 대한 참조도 포함하는 동안 가 설정된 경우에 DisableJavaScriptProxies 발생합니다. 프록시를 수동으로 만드는 방법에 대한 자세한 내용은 생성된 프록시 및 프록시가 수행하는 작업을 참조하세요.

"연결 ID가 잘못된 형식입니다." 또는 "활성 SignalR 연결 중에 사용자 ID를 변경할 수 없습니다." 오류

인증을 사용하고 연결이 중지되기 전에 클라이언트가 로그아웃된 경우 이 오류가 표시될 수 있습니다. 해결 방법은 클라이언트를 로그아웃하기 전에 SignalR 연결을 중지하는 것입니다.

"Catch되지 않은 오류: SignalR: jQuery를 찾을 수 없습니다. SignalR.js 파일" 오류 전에 jQuery가 참조되었는지 확인하세요.

SignalR JavaScript 클라이언트를 실행하려면 jQuery가 필요합니다. jQuery에 대한 참조가 올바른지, 사용된 경로가 유효한지, jQuery에 대한 참조가 SignalR에 대한 참조 앞에 있는지 확인합니다.

"Catch되지 않은 TypeError: 정의되지 않은 속성 '<property>'를 읽을 수 없습니다." 오류

이 오류는 jQuery 또는 허브 프록시가 제대로 참조되지 않아 발생합니다. jQuery 및 허브 프록시에 대한 참조가 올바른지, 사용된 경로가 유효한지, jQuery에 대한 참조가 허브 프록시에 대한 참조 앞에 있는지 확인합니다. 허브 프록시에 대한 기본 참조는 다음과 같습니다.

허브 프록시를 올바르게 참조하는 HTML 클라이언트 쪽 코드

<script src="/signalr/hubs"></script>

"RuntimeBinderException이 사용자 코드에 의해 처리되지 않았습니다." 오류

이 오류는 의 Hub.On 잘못된 오버로드를 사용할 때 발생할 수 있습니다. 메서드에 반환 값이 있는 경우 반환 형식을 제네릭 형식 매개 변수로 지정해야 합니다.

클라이언트에 정의된 메서드(생성된 프록시 없음)

MyHub.On<ReturnType>("MethodName", LocalMethod);

연결 ID가 일치하지 않거나 페이지 로드 간에 연결이 끊어지거나

이 동작은 의도된 것입니다. 허브 개체는 페이지 개체에 호스트되므로 페이지가 새로 고쳐지면 허브가 제거됩니다. 여러 페이지 애플리케이션은 페이지 로드 간에 일관성을 유지할 수 있도록 사용자와 연결 ID 간의 연결을 유지해야 합니다. 연결 ID는 개체 또는 데이터베이스의 서버에 ConcurrentDictionary 저장할 수 있습니다.

"값은 null일 수 없습니다." 오류

선택적 매개 변수가 있는 서버 쪽 메서드는 현재 지원되지 않습니다. 선택적 매개 변수를 생략하면 메서드가 실패합니다. 자세한 내용은 선택적 매개 변수를 참조하세요.

Firebug의 "Firefox가 주소>에 <있는 서버에 대한 연결을 설정할 수 없습니다." 오류

WebSocket 전송 협상이 실패하고 다른 전송이 대신 사용되는 경우 Firebug에서 이 오류 메시지를 볼 수 있습니다. 이 동작은 의도된 것입니다.

.NET 클라이언트 애플리케이션의 "유효성 검사 절차에 따라 원격 인증서가 잘못되었습니다." 오류

서버에 사용자 지정 클라이언트 인증서가 필요한 경우 요청이 이루어지기 전에 연결에 x509certificate를 추가할 수 있습니다. 를 사용하여 Connection.AddClientCertificate연결에 인증서를 추가합니다.

인증 시간이 초과된 후 연결이 끊어짐

이 동작은 의도된 것입니다. 연결이 활성화된 동안에는 인증 자격 증명을 수정할 수 없습니다. 자격 증명을 새로 고치려면 연결을 중지하고 다시 시작해야 합니다.

jQuery Mobile을 사용할 때 OnConnected가 두 번 호출됩니다.

jQuery Mobile의 initializePage 함수는 각 페이지의 스크립트를 강제로 다시 실행하여 두 번째 연결을 만듭니다. 이 문제에 대한 해결 방법은 다음과 같습니다.

  • JavaScript 파일 앞에 jQuery Mobile에 대한 참조를 포함합니다.
  • 를 설정하여 함수를 initializePage 사용하지 않도록 설정합니다 $.mobile.autoInitializePage = false.
  • 연결을 시작하기 전에 페이지 초기화가 완료되기를 기다립니다.

서버 전송 이벤트를 사용하여 Silverlight 애플리케이션에서 메시지가 지연됨

Silverlight에서 서버 전송 이벤트를 사용할 때 메시지가 지연됩니다. 대신 긴 폴링을 강제로 사용하려면 연결을 시작할 때 다음을 사용합니다.

connection.Start(new LongPollingTransport());

Forever Frame 프로토콜을 사용하는 "사용 권한 거부됨"

이것은 알려진 문제이며 여기에 설명되어 있습니다. 이 증상은 최신 JQuery 라이브러리를 사용하여 볼 수 있습니다. 해결 방법은 애플리케이션을 JQuery 1.8.2로 다운그레이드하는 것입니다.

컴파일 및 서버 쪽 오류

다음 섹션에는 컴파일러 및 서버 쪽 런타임 오류에 대한 가능한 솔루션이 포함되어 있습니다.

허브 instance 대한 참조가 null입니다.

각 연결에 대해 허브 instance 만들어지므로 코드에서 허브의 instance 직접 만들 수 없습니다. 허브 자체 외부에서 허브에서 메서드를 호출하려면 허브 컨텍스트에 대한 참조를 가져오는 방법은 허브 클래스 외부에서 클라이언트 메서드를 호출하고 그룹을 관리하는 방법을 참조하세요.

HTTPContext.Current.Session이 null임

이 동작은 의도된 것입니다. SignalR은 세션 상태를 사용하도록 설정하면 이중 메시징이 중단되므로 ASP.NET 세션 상태를 지원하지 않습니다.

재정의하기에 적합한 방법이 없습니다.

이전 설명서 또는 블로그의 코드를 사용하는 경우 이 오류가 표시 될 수 있습니다. 변경되거나 사용되지 않는 메서드의 이름(예: OnConnectedAsync)을 참조하지 않는지 확인합니다.

HostContextExtensions.WebSocketServerUrl이 null입니다.

이 동작은 의도된 것입니다. 이 멤버는 더 이상 사용되지 않으므로 사용하지 않아야 합니다.

"'signalr.hubs'라는 경로가 경로 컬렉션에 이미 있습니다." 오류

애플리케이션에서 이 두 번 호출되면 MapHubs 이 오류가 표시됩니다. 일부 예제 애플리케이션은 전역 애플리케이션 파일에서 직접 호출 MapHubs 하고 다른 예제는 래퍼 클래스에서 호출합니다. 애플리케이션이 둘 다 수행하지 않는지 확인합니다.

Visual Studio 문제

이 섹션에서는 Visual Studio에서 발생한 문제에 대해 설명합니다.

스크립트 문서 노드가 솔루션 탐색기 표시되지 않습니다.

일부 자습서에서는 디버깅하는 동안 솔루션 탐색기 "문서 스크립트" 노드로 안내합니다. 이 노드는 JavaScript 디버거에서 생성되며 인터넷 Explorer 브라우저 클라이언트를 디버깅하는 동안에만 표시됩니다. Chrome 또는 Firefox를 사용하는 경우에는 노드가 나타나지 않습니다. Silverlight 디버거와 같은 다른 클라이언트 디버거가 실행 중인 경우에도 JavaScript 디버거가 실행되지 않습니다.

SignalR이 Visual Studio 2008 이하에서 작동하지 않음

이 동작은 의도된 것입니다. SignalR에는 .NET Framework 4 이상이 필요합니다. 이를 위해서는 SignalR 애플리케이션을 Visual Studio 2010 이상에서 개발해야 합니다.

IIS 문제

이 섹션에는 인터넷 정보 서비스 관련 문제가 포함되어 있습니다.

MapHubs 호출 후 웹 사이트 충돌

이 문제는 최신 버전의 SignalR에서 해결되었습니다. NuGet을 사용하여 설치를 업데이트하여 최신 버전의 SignalR을 사용하고 있는지 확인합니다.

Azure 문제

이 섹션에는 Microsoft Azure 관련 문제가 포함되어 있습니다.

토픽 이름을 변경한 후 Azure 백플레인을 통해 메시지가 수신되지 않음

Azure 백플레인에서 사용하는 topics 사용자 구성이 불가능합니다.