receiveMessage Event not calling SignalR

不打扰是莪最后的温柔 提交于 2020-05-17 06:01:37

问题


SignalR.core.1.1.0, asp.net core 2.2

i am learning SignalR these days.i want to send message to specific identity user with Their Email address.my ViewModel Contains fields like Username(Email) where message should send, SenderId,Text,date. But problem is connection.on('receiveMessage', addMessageToChat) is not hit even Hub method is calling. Below is my code

    <div class="card-footer">
                    <form asp-controller="Home" asp-action="Create"
                          data-ajax-begin="clearInputField" data-ajax-complete=""
                          data-ajax-failure="alert('Fail')" data-ajax-success="sendMessage"
                          data-ajax="true" data-ajax-method="POST">
                        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                        <div class="input-group">

                            <input type="text" name="UserName" id="UserName" value="" hidden />
                            <textarea name="Text" id="Text" class="form-control type_msg" placeholder="Type your message..."></textarea>
                            <div class="input-group-append">
                                <button type="submit" id="submitButton" class="input-group-text send_btn"><i class="fas fa-location-arrow"></i></button>
                            </div>
                        </div>
                    </form>
</div>

class Message {
    constructor(username, text, when) {
        this.userName = username;
        this.text = text;
        this.when = when;
    }
}
const messagesQueue = [];

function clearInputField() {
    const text = document.getElementById('Text');
    messagesQueue.push(text.value);
    text.value = "";
    console.log("from Clear")
}

function sendMessage() {
    const username = document.getElementById('UserName').value;  
    let text = messagesQueue.shift() || "";
    if (text.trim() === "") return;

    let currentdate = new Date();
    let when =
        (currentdate.getMonth() + 1) + "/"
        + currentdate.getDate() + "/"
        + currentdate.getFullYear() + " "
        + currentdate.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true })
    let message = new Message(username, text,when);
    sendMessageToHub(message);
}
function addMessageToChat(message) {
    console.log("from chat" + message);
    const username = document.getElementById('UserName'); 
    let isCurrentUserMessage = message.userName === username;
    var currentdate = new Date();
    const d =
        (currentdate.getMonth() + 1) + "/"
        + currentdate.getDate() + "/"
        + currentdate.getFullYear() + " "
        + currentdate.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true })
    var image = document.getElementById('userImg').value;
    let className = isCurrentUserMessage ? "justify-content-end" :"justify-content-start";
    var msg = message.text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
    var encodedMsg = ` <div class="d-flex ${className} mb-4">
                                                    <div class="img_cont_msg">
                                                      <img src="${image}" class="rounded-circle user_img_msg">
                                                    </div>
                                                    <div class="msg_cotainer">
                                                       ${msg}
                                                        <span class="msg_time">${message.when}</span>
                                                    </div>
                                               </div>`;
    var li = document.createElement("div");
    li.textContent = encodedMsg;
    document.getElementById("chat").appendChild(li);
}

My Chat.js

    var connection = new signalR.HubConnectionBuilder()
    .withUrl('/messages')
    .build();

connection.on('ReceiveMessage', addMessageToChat)

connection.start()
    .catch(error => {
        console.error(error.message);
    });

function sendMessageToHub(message) {
    connection.invoke('SendMessage', message);
}

C# Hub

 public async Task SendMessage(MessageViewModel message)
        {
            var user = await UserManager.FindByNameAsync(message.UserName);
            //string userid = Context.UserIdentifier;
            var Claims = new Claim(ClaimTypes.NameIdentifier,user.Id).Value;
            await Clients.User(Claims).SendAsync("ReceiveMessage",message.UserName, message);
        }

回答1:


The .User(..) property on the Hub requires you to somehow register your users (in this case email addresses). This is done automatically for you by the SignalR framework, as long as you sign in your users.

Now, I did this in ASP.NET Core 3.1, mainly because I don't have the 2.2 SDK installed on my computer.

Make sure you have a way of persisting user claims (easiest is to use Cookies)

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddSignalR();

        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie();

        services.AddAuthorization();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseStaticFiles();

        app.UseAuthentication();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute();

            endpoints.MapHub<ChatHub>("/messages");
        });
    }
}

When a user first enrolls/register with your site, you need to authenticate them. Once that is done. This is the critical part to get your .User(..) working:

You must call SignInAsync(..) and pass in an identity that has the ClaimTypes.NameIdentifier

[HttpPost]
public async Task<IActionResult> Login([FromForm]LoginViewModel loginViewModel)
{
    // Perform actual authentication
    // We're just assuming it was successful
    var nameClaim = new Claim(ClaimTypes.NameIdentifier, loginViewModel.EmailAddress);
    var identity = new ClaimsIdentity(new List<Claim>{ nameClaim }, "AutoVerified");
    var principal = new ClaimsPrincipal(identity);
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);

    // Once we know we have a valid user and have logged in using cookies, we can redirect to the message index
    return RedirectToAction("Index", "Message");
}

My message index is super simple, but you need the [Authorize] attribute, otherwise the framework won't verify you have a logged in user accessing your hub.

[Authorize]
public class MessageController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}


来源:https://stackoverflow.com/questions/61613021/receivemessage-event-not-calling-signalr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!