首页 > 技术文章 > vue js 和signalr 结合实现消息推送1

vktun 2017-07-21 15:57 原文

由于signalr2.2.0 依赖于jQuery,虽然在vuejs 略显臃肿, 但是对于目前刚接触 vuejs 和想实现 前后分离的我来说 这已经很好了。目前先实现功能, 然后如果有时间或者期望大牛将signalr 改成不依赖jQuery的signalr.项目结构是分服务端asp.net webAPI 前端vuejs。所以牵扯到跨域的问题,但是目前的signalr 版本已经支持,只有服务端支持跨域就可以了。由于时间关系先简略记下当前的主要解决方法。


服务端:

asp.net webapi

  1 using System.Threading.Tasks;
  2 using Microsoft.AspNet.SignalR;
  3 using System.Collections.Generic;
  4 
  5 namespace DMS.WebApi.Hubs
  6 {
  7 /// < summary>
  8 /// SmartEMSHub 这是我们要定义的hub
  9 /// </ summary>
 10 public class SmartEMSHub : Hub
 11 {
 12 /// < summary>
 13 /// 
 14 /// </ summary>
 15 public static List<string> Users = new List<string>();
 16 
 17 /// <summary>
 18 /// The OnConnected event.
 19 /// </summary>
 20 /// <returns></returns>
 21 public override Task OnConnected()
 22 {
 23 string clientId = GetClientId();
 24 if (Users.IndexOf(clientId) == -1)
 25 {
 26 Users.Add(clientId);
 27 }
 28 Send(Users.Count);
 29 var context = GlobalHost.ConnectionManager.GetHubContext<SmartEMSHub>();
 30 context.Clients.Client(clientId).updateUserName(clientId);
 31 return base.OnConnected();
 32 }
 33 
 34 /// <summary>
 35 /// The OnReconnected event.
 36 /// </summary>
 37 /// <returns></returns>
 38 public override Task OnReconnected()
 39 {
 40 string clientId = GetClientId();
 41 if (Users.IndexOf(clientId) == -1)
 42 {
 43 Users.Add(clientId);
 44 }
 45 Send(Users.Count);
 46 return base.OnReconnected();
 47 }
 48 
 49 /// <summary>
 50 /// The OnDisconnected event.
 51 /// </summary>
 52 /// <param name="stopCalled"></param>
 53 /// <returns></returns>
 54 public override Task OnDisconnected(bool stopCalled)
 55 {
 56 string clientId = GetClientId();
 57 
 58 if (Users.IndexOf(clientId) > -1)
 59 {
 60 Users.Remove(clientId);
 61 }
 62 Send(Users.Count);
 63 return base.OnDisconnected(stopCalled);
 64 }
 65 
 66 /// <summary>
 67 /// Get's the currently connected Id of the client.
 68 /// This is unique for each client and is used to identify
 69 /// a connection.
 70 /// </summary>
 71 /// <returns></returns>
 72 private string GetClientId()
 73 {
 74 string clientId = "";
 75 
 76 // clientId passed from application 
 77 if (Context.QueryString["clientId"] != null)
 78 {
 79 clientId = this.Context.QueryString["clientId"];
 80 }
 81 
 82 if (string.IsNullOrEmpty(clientId.Trim()))
 83 {
 84 clientId = Context.ConnectionId;
 85 }
 86 
 87 return clientId;
 88 }
 89 
 90 /// <summary>
 91 /// Sends the update user count to the listening view.
 92 /// </summary>
 93 /// <param name="count">
 94 /// The count.
 95 /// </param>
 96 public void Send(int count)
 97 {
 98 // Call the addNewMessageToPage method to update clients.
 99 var context = GlobalHost.ConnectionManager.GetHubContext<SmartEMSHub>();
100 context.Clients.All.updateUsersOnlineCount(count);
101 }
102 /// <summary>
103 /// 自己写的一个服务端方法Hello.
104 /// </summary>
105 /// <param name="msg">参数
106 /// </param>
107 public void Hello(string msg)
108 {
109 var context = GlobalHost.ConnectionManager.GetHubContext<SmartEMSHub>();
110 context.Clients.All.clientMethod("server:"+msg);
111 }
112 }
113 }

 

当然还要支持跨域

 1 using Microsoft.AspNet.SignalR;
 2 using Microsoft.Owin;
 3 using Microsoft.Owin.Cors;
 4 using Owin;
 5 
 6 [assembly: OwinStartup(typeof(DMS.WebApi.Hubs.Startup))]
 7 namespace DMS.WebApi.Hubs
 8 {
 9 public class Startup
10 {
11 public void Configuration(IAppBuilder app)
12 {
13 // 连接标识
14 app.Map("/signalr", map =>
15 {
16 //跨域
17 map.UseCors(CorsOptions.AllowAll);
18 var hubConfiguration = new HubConfiguration
19 {
20 EnableJSONP = true
21 };
22 //启动配置
23 map.RunSignalR(hubConfiguration);
24 });
25 }
26 }
27 }

 

> Javascript client(vuejs)

客户端利用webpack 来使用时 发现很难 动态加载<code>../signalr/hub</code> 于是找到了另一种方式来解决这个问题

我这里只做了一个组件, 其他方式应该也是可以

 <template>
    <div>
        signalr connect
        <div>
            <div>{{showmsg}}< /div>
            <input v-model="value" placeholder="请输入..." />
            <Button type="info" @click="sendMsg">信息按钮</Button>
        </div>
    </div>
    </template>
    <script>
    import $ from 'jquery'
    import signalR from '../assets/js/signalr.2.2.2.js'
    // import Hubs from '../signalr/hubs'
    export default {
    name: "Signalr",
    data() {
        return {
            value: "",
            showmsg: "222",
            proxy: {}
        }
    },
    mounted() {
        var $this = this;
        $this.connectServer();
    },
    methods: {
        connectServer() {
            var $this = this;
            var conn = $.hubConnection("http://localhost:52656/signalr", { qs: "clientId=1232222" })
            $this.proxy = conn.createHubProxy("smartEMSHub");
            $this.getMsg();
            conn.start().done((data) => {
                $this.sendMsg();
            }).fail((data) => {
            });
        },
        sendMsg() {
            var $this = this;
            $this.proxy.invoke("Hell", $this.value).done((msg) => {
            });
        },
        getMsg() {
            var $this = this;
            $this.proxy.on("clientMethod", (data) => {
                $this.showmsg = data;
            })
        }
    }
    }
    </script>

    <style>

    </style>

 

--------------------------
2017年7月21日 由于时间仓促,还待补充

推荐阅读