vue +signalR


系列

源碼地址:https://github.com/QQ2287991080/SignalRServerAndVueClientDemo

概述:ASP.NET Core SignalR是一種開放源代碼庫,可簡化將實時 web 功能添加到應用程序的功能。 實時 web 功能使服務器端代碼可以立即將內容推送到客戶端。

這玩意的概念我就不多講了,官方文檔:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/introduction?view=aspnetcore-3.0

今天這個demo,就是用SignalR 做服務端,vue做客戶端。

以下演示皆為本地環境

先看看最終效果

 

 

上代碼

先建一個項目,我core的版本是3.0,我選擇的應用“Web應用程序”,其實我這創建的就跟官網的JavaScript教程一樣的。

項目建好之后右鍵項目->添加>客戶端庫

 

按圖上添加就好了

 把Pages下面的Index視圖的代碼換成如下:

@page
<div class="container">
    <div class="row">&nbsp;</div>
    <div class="row">
        <div class="col-2">User</div>
        <div class="col-4"><input type="text" id="userInput" /></div>
    </div>
    <div class="row">
        <div class="col-2">Message</div>
        <div class="col-4"><input type="text" id="messageInput" /></div>
    </div>
    <div class="row">&nbsp;</div>
    <div class="row">
        <div class="col-6">
            <input type="button" id="sendButton" value="Send Message" />
        </div>
    </div>
</div>
<div class="row">
    <div class="col-12">
        <hr />
    </div>
</div>
<div class="row">
    <div class="col-6">
        <ul id="messagesList"></ul>
    </div>
</div>
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>

在放靜態文件的wwwroot的js下面新建一個chat.js,並放入如下代碼

"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

//Disable send button until connection is established
document.getElementById("sendButton").disabled = true;

connection.on("ReceiveMessage", function (user, message) {
    var msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
    var encodedMsg = user + " says " + msg;
    var li = document.createElement("li");
    li.textContent = encodedMsg;
    document.getElementById("messagesList").appendChild(li);
});

connection.start().then(function () {
    document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
    return console.error(err.toString());
});

document.getElementById("sendButton").addEventListener("click", function (event) {
    var user = document.getElementById("userInput").value;
    var message = document.getElementById("messageInput").value;
    connection.invoke("SendMessage", user, message).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
});

添加SignalR中心,加個Hubs文件夾,加個ChatHub類

public class ChatHub : Hub
    {
        /// <summary>
        /// 給所有客戶端發送消息
        /// </summary>
        /// <param name="user">用戶</param>
        /// <param name="message">消息</param>
        /// <returns></returns>
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
        /// <summary>
        /// 向調用客戶端發送消息(備用)
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendMessageCaller(string message)
        {
            await Clients.Caller.SendAsync("ReceiveCaller", message);
        }
    }

在Startup里配置SignalR

ConfigureServices里加上

services.AddSignalR();

Configure

         app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
                endpoints.MapHub<ChatHub>("/chathub");
            });

看看效果

是不是有聊天室那味了。。

哎呀不對,標題咋不說要弄vue做客戶端啊,咋現在還在這寫視圖呢。

那么接下來就用vue做客戶端,我用的腳手架,引用vue.js也是能實現的。

先用腳手架建一個項目,把不要的東西都刪除,只留下一個home.vue,記得路由里面也刪除干凈,要不然會報錯的。

首先我們先安裝前端的js包,上文也看到我們調用signalr中心有對應的js客戶端

npm install @aspnet/signalr

安裝好之后,我們開始寫前端代碼

在home.vue里面放兩個輸入框和一個按鈕,和core的index視圖差不多,樣式就不美化,主要做效果。

    <input v-model="user" type="text" />
    <input v-model="message" type="text" />
    <button @click="sendAll">發送全部</button>

引用安裝的@aspnet/signalr

import * as signalR from "@aspnet/signalr";

定義需要的變量

data() {
    return {
      user: "",//用戶
      message: "",//消息
      connection: "",//signalr連接
      messages: []//返回消息
    };
  },

定義頁面加載連接signalr

created: function() {
    let thisVue = this;
    this.connection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:13989/chathub", {
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
      })
      .configureLogging(signalR.LogLevel.Information)
      .build();
    this.connection.on("ReceiveMessage", function(user, message) {
      thisVue.messages.push({ user, message });
      console.log({ user, message });
    });
    this.connection.start();
  }

給按鈕來個點擊事件

 methods: {
    //給全部發送消息
    sendAll: function() {
      this.connection
        .invoke("SendMessage", this.user, this.message)
        .catch(function(err) {
          return console.error(err);
        });
    }
}

🆗。把代碼跑起來,npm run serve........

 

 

等一下,先把我們的后端跑起來,要不然是接受不到的。

 

 測試看看先。。

 

 數據拿到了,忘記展示了,先加個<ul>

 <div>
      <ul v-for="(item ,index) in messages" v-bind:key="index +'itemMessage'">
        <li>{{item.user}} says {{item.message}}</li>
      </ul>
    </div>

我再加個標題吧好看點。

 

 哎。有內味兒了。

不知道還有人記得之前chahub里面我預留了一個給自己發消息的方法。

嘿,這會兒就給他實現一下,首先我先加個按鈕,然后在注冊給自己發送的方法。這回我代碼就不填出來,先看看效果,之后代碼全都給出來。

 

 來了來了,壓縮囂張至極。。。

先把前端代碼放出來,完整版

<template>
  <div class="home">
    <h1>前端演示SignalR</h1>
    <input v-model="user" type="text" />
    <input v-model="message" type="text" />
    <button @click="sendAll">發送全部</button>
    <button @click="sendOwn">對自己發送</button>
    <div>
      <ul v-for="(item ,index) in messages" v-bind:key="index +'itemMessage'">
        <li>{{item.user}} says {{item.message}}</li>
      </ul>
    </div>
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";
import * as signalR from "@aspnet/signalr";
export default {
  name: "Home",
  components: {
    HelloWorld
  },
  data() {
    return {
      user: "", //用戶
      message: "", //消息
      connection: "", //signalr連接
      messages: [] //返回消息
    };
  },
  methods: {
    //給全部發送消息
    sendAll: function() {
      this.connection
        .invoke("SendMessage", this.user, this.message)
        .catch(function(err) {
          return console.error(err);
        });
    },
    //只給自己發送消息
    sendOwn: function() {
      this.connection
        .invoke("SendMessageCaller", this.message)
        .catch(function(err) {
          return console.error(err);
        });
    }

 
  },
  created: function() {
    let thisVue = this;
    this.connection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:13989/chathub", {
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
      })
      .configureLogging(signalR.LogLevel.Information)
      .build();
    this.connection.on("ReceiveMessage", function(user, message) {
      thisVue.messages.push({ user, message });
      console.log({ user, message });
    });
    this.connection.on("ReceiveCaller", function(message) {
      let user = "自己";//這里為了push不報錯,我就弄了一個默認值。
      thisVue.messages.push({ user, message });
      console.log({ user, message });
    });
    this.connection.start();
  }
};
</script>

完結!!!

這個其實還是不是特別我完整,下次有時間把中心服務到客戶端的也搞出來大伙看看。

中心往外部發送

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM