web-dev-qa-db-ja.com

サーバー側の信号からクライアントを切断する

フォーム認証付きのMVC4 C#WebアプリケーションでSignalR 1を使用しています。 JavaScriptのレイアウトページにコードがあります。

$(documnet).ready(function(){
       connect to hub code ...
})

ユーザーをハブから切断し、ログインして検証が完了したら、接続を再開します。私は私のアカウントコントローラとメソッド内のサーバー側からそれをしたいです:

public ActionResult LogOn(LoginModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        if (System.Web.Security.Membership.ValidateUser(model.UserName, model.Password))
        {
            FormsAuthentication.SetAuthCookie(model.UserName, false);
            ....here , disconnect from hub
            ....to make the user reconnect     
}

私がそれをしたい理由は、ユーザーがログイン後に認証済みに変更され、接続が残っている場合、SignalRがエラーをスローするためです。エラーは:

接続IDの形式が正しくありません。

13
Haddar Macdasi

サーバーからSignalR接続を停止および開始することはできません。電話する必要があります

$.connection.hub.stop(); //on the client before the user attempts to log on and then call 
$.connection.hub.start(); //after the log on attempt has completed.
25
halter73

サーバーがSignalRを介して呼び出すことができる切断イベントをクライアントに書き込むことは、要求することを実行できる1つの方法です。多分このようなものかもしれません:

myHub.client.serverOrderedDisconnect = function (value) {
    $.connection.hub.stop();
};

次に、サーバー上で次のようにします。

Clients.Client(Context.ConnectionId).serverOrderedDisconnect();
12
UtopiaLtd

JavaScriptからすべてを制御してみてください。以下はログアウトの例です。ログインも同様です。

から http://www.asp.net/signalr/overview/security/introduction-to-security

アクティブな接続が存在するときにユーザーの認証ステータスが変化すると、ユーザーは「アクティブなSignalR接続中はユーザーIDを変更できない」というエラーを受け取ります。その場合、アプリケーションはサーバーに再接続して、接続IDとユーザー名が調整されていることを確認する必要があります。たとえば、アクティブな接続が存在しているときにユーザーがログアウトすることをアプリケーションが許可している場合、接続のユーザー名は次のリクエストで渡される名前と一致しなくなります。ユーザーがログアウトする前に接続を停止してから、再起動する必要があります。

ただし、ほとんどのアプリケーションでは接続を手動で停止および開始する必要がないことに注意することが重要です。アプリケーションがログアウト後にユーザーを別のページにリダイレクトする場合(WebフォームアプリケーションやMVCアプリケーションのデフォルトの動作など)、またはログアウト後に現在のページを更新する場合、アクティブな接続は自動的に切断され、追加のアクションは必要ありません。

次の例は、ユーザーのステータスが変更されたときに接続を停止および開始する方法を示しています。

<script type="text/javascript">
$(function () {
    var chat = $.connection.sampleHub;
    $.connection.hub.start().done(function () {
        $('#logoutbutton').click(function () {
            chat.connection.stop();
            $.ajax({
                url: "Services/SampleWebService.svc/LogOut",
                type: "POST"
            }).done(function () {
                chat.connection.start();
            });
        });
    });
});
4
Matt G

誰かがまだ解決策を探している場合(SignalRバージョン2.4.1):

GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections().First(c => c.ConnectionId == "YourId").Disconnect();

これを試して:

public ActionResult LogOn(LoginModel model, string returnUrl) {
    if (ModelState.IsValid) {
        if (System.Web.Security.Membership.ValidateUser(model.UserName, model.Password)) {
            FormsAuthentication.SetAuthCookie(model.UserName, false);
            connection.Stop();
        }
}

接続ハンドルがconnectionであると仮定します。問題は、アクションメソッドでconnectionオブジェクトへのハンドルにアクセスすることです。

1
Dave Alperovich