signalr 應用於微信小程序(一)


前言

在2017年基於signalr 和微信小程序 寫的腳本。

正文

先安裝signalr:

1.安裝singalr,用nutget就行,用這個包管理就行。

2.使用singalr

3.根據singalr的調用模式來開發singalr的客戶端。

安裝singalr,非core,后面我們會介紹core的。

我用的是2.23,那么開始上代碼了

引用:

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

集成:

[HubName("ChatHub")]
public class ChatHub : Hub
{
}

HubName是重命名ChatHub,不然的話,signalr 默認使用后類名的小寫作為路由。

//已經連接
public override async Task OnConnected()
{
	Console.WriteLine("連接成功");
}
//恢復連接
public override Task OnReconnected()
{
	return base.OnReconnected();
}
//斷開連接
public override Task OnDisconnected(bool stopCalled)
{
}

在程序啟動后啟動該程序:

在Startup 中如下:

using Microsoft.Owin;
using Owin;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;

[assembly: OwinStartupAttribute(typeof(ThinkingSpace.Startup))]
namespace ThinkingSpace
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            //允許跨域
            app.UseCors(CorsOptions.AllowAll);
            app.MapSignalR();
        }
    }
}

下面是完整的ChatHub:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Comment;
using Comment.time;
using ThinkingSpace.Models;
using objectJson;
using objectJson.Chat;
//using Comment.everyday;
namespace ThinkingSpace.Chat
{
    [HubName("ChatHub")]
    public class ChatHub : Hub
    {
   public   static   List<Users>  userList = new List<Users>();
        /// <summary>
        /// 注冊群組 注冊用戶信息
        /// </summary>
        /// <param name="groupid">群組ID</param>
        public void Group(string groupid)
        {

           friendsInformation friends = new friendsInformation();
            friends.id = 1;
            friends.list.AddRange(userList);
            mineinformation mine = new mineinformation();
            init begin = new init();
            var thisuser = userList.Where(u => u.id == Context.ConnectionId).FirstOrDefault();
            if (thisuser == null)
            {
                Users user = new Users();
                Random rd = new Random();
                mine.id=user.id = rd.Next(100).ToString();
                user.username=mine.username= Comment.Math.RandomLength.GenerateRandomNumber(10);
                user.conId = Context.ConnectionId;
                Clients.AllExcept(Context.ConnectionId).newUser(user);
                userList.Add(user);
            }
            begin.mine = mine;
            List<friendsInformation> fr = new List<friendsInformation>();
            fr.Add(friends);
            List<groupInformation> group = new List<groupInformation>();
            group.Add(new groupInformation());
            begin.friend = fr;
            begin.group = group;
            Groups.Add(Context.ConnectionId, groupid);
            //通知所有人在線
            Clients.Client(Context.ConnectionId).addNewMessageToPage(begin);
        }
        public void getAlluser() {

        }
        public void sendtest(string yes)
        {
            Console.WriteLine("yes");
        }
        /// <summary>
        /// 發送消息 自定義判斷是發送給全部用戶還是某一個組(類似於群聊啦)
        /// </summary>
        public void Send(mineAndto data)
        {
            long timestamp = AllOfTime.DataToTimeStamp();
            // username: "紙飛機" //消息來源用戶名
            //,avatar: "http://tp1.sinaimg.cn/1571889140/180/40030060651/1" //消息來源用戶頭像
            //,id: "100000" //聊天窗口來源ID(如果是私聊,則是用戶id,如果是群聊,則是群組id)
            //,type: "friend" //聊天窗口來源類型,從發送消息傳遞的to里面獲取
            //,content: "嗨,你好!本消息系離線消息。" //消息內容
            //,mine: false //是否我發送的消息,如果為true,則會顯示在右方
            //,timestamp: 1467475443306 //服務端動態時間戳
            sendTo To = data.To;
            sendmine mine = data.mine;
            Message ms = new Message();
            ms.username = mine.username;
            ms.avatar = mine.avatar;
            ms.id = To.id;
            ms.content = mine.content;
            ms.mine = false;
            ms.type = To.type;
            ms.timestamp = timestamp;
            Clients.Group("123",Context.ConnectionId).SendAsync(ms);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        public void SendSingle(mineAndto data)
        {

            long timestamp = AllOfTime.DataToTimeStamp();
            // username: "紙飛機" //消息來源用戶名
            //,avatar: "http://tp1.sinaimg.cn/1571889140/180/40030060651/1" //消息來源用戶頭像
            //,id: "100000" //聊天窗口來源ID(如果是私聊,則是用戶id,如果是群聊,則是群組id)
            //,type: "friend" //聊天窗口來源類型,從發送消息傳遞的to里面獲取
            //,content: "嗨,你好!本消息系離線消息。" //消息內容
            //,mine: false //是否我發送的消息,如果為true,則會顯示在右方
            //,timestamp: 1467475443306 //服務端動態時間戳
            sendTo To = data.To;
            sendmine mine = data.mine;
            var user=userList.Where(u => u.username == To.username).FirstOrDefault();
            if (user != null)
            {
                Message ms = new Message();
                ms.username = mine.username;
                ms.avatar = mine.avatar;
                ms.id = To.id;
                ms.content = mine.content;
                ms.mine = false;
                ms.type = To.type;
                ms.timestamp = timestamp;
                Clients.Client(user.conId).SendAsync(ms);
            }
            else
            {
                sysmessage sms = new sysmessage();
                sms.type = To.type;
                sms.id = To.id;
                Clients.Client(Context.ConnectionId).SendAsync(sms);
            }
        }
        //使用者離線
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stopCalled"></param>
        /// <returns></returns>
        public override Task OnDisconnected(bool stopCalled)
        {
            var user = userList.Where(u => u.conId == Context.ConnectionId).FirstOrDefault();
            if (user != null)
            {
                userList.Remove(user);
                Clients.AllExcept(Context.ConnectionId).RemoveUser(user);
            }

            return base.OnDisconnected(true);
        }
        public override async Task OnConnected()
        {
            Console.WriteLine("連接成功");
        }
        /// <summary>
        /// </summary>
        /// <returns></returns>
        public override Task OnReconnected()
        {
            return base.OnReconnected();
        }
      }
    }

在瀏覽器前端有兩種連接方式,一種是本地快捷版,一種是遠程速度版。

本地快捷版:

<script>
        var chathub = $.connection.ChatHub;
        $(function () {
            $.connection.hub.start().done(function () {
                //新建對象
                chathub.invoke("Group", "123");
                console.log("成功調用起");
            })
            $('.layim-chat-text img').zoomify();
        })
        //chat.client.SendAsync = function (name, data) {
        //            $('#msglist').append($('<li>').text(data));
        //}
</script>

遠程速度版:

<script>
	//var chathub = $.connection.ChatHub;
	var connection = $.hubConnection('http://localhost:55921');//如果前后端為同一個端口,可不填參數。如果前后端分離,這里參數為服務器端的URL
	var chathub = connection.createHubProxy('ChatHub');
	$(function () {
		//$.connection.hub.start().done(function () {
		//    //新建對象
		//    chathub.invoke("Group", "123");
		//    console.log("成功調用起");
		//})
		connection.start().done(function () {
			console.log('Now connected, connection ID=' + connection.id);
			chathub.invoke("Group", "123");
			console.log("成功調用起");
			chathub.invoke("sendtest", "123");
		}).fail(function (error) {
			console.log('Could not connect');
			console.log(error);
		});
		$('.layim-chat-text img').zoomify();
	})
	//chat.client.SendAsync = function (name, data) {
	//            $('#msglist').append($('<li>').text(data));
	//}
</script>

完整案例:

我是基於layim:

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
    <meta name="format-detection" content="telephone=no">
    <title>im 通訊</title>
    <link href="~/layim.std/layim-v3.7.7/dist/css/layui.mobile.css" rel="stylesheet" />
</head>
<body>
    <script src="~/Scripts/jquery-1.12.1.js"></script>
    @*<script src="~/Scripts/jquery.signalR-2.2.3.js"></script>*@
    <script src="~/Scripts/jquery.signalR-2.2.3.js"></script>
    <script src="~/layim.std/layim-v3.7.7/dist/layui.js"></script>
    <link href="~/Scripts/dist/zoomify.min.css" rel="stylesheet" />
    <script src="~/Scripts/dist/zoomify.min.js"></script>
    <script>
        //var chathub = $.connection.ChatHub;
        var connection = $.hubConnection('http://localhost:55921');//如果前后端為同一個端口,可不填參數。如果前后端分離,這里參數為服務器端的URL
        var chathub = connection.createHubProxy('ChatHub');
        $(function () {
            //$.connection.hub.start().done(function () {
            //    //新建對象
            //    chathub.invoke("Group", "123");
            //    console.log("成功調用起");
            //})
            connection.start().done(function () {
                console.log('Now connected, connection ID=' + connection.id);
                chathub.invoke("Group", "123");
                console.log("成功調用起");
                chathub.invoke("sendtest", "123");
            }).fail(function (error) {
                console.log('Could not connect');
                console.log(error);
            });
            $('.layim-chat-text img').zoomify();
        })
        //chat.client.SendAsync = function (name, data) {
        //            $('#msglist').append($('<li>').text(data));
        //}
    </script>
    <script>
layui.config({
  version: true
}).use('mobile', function(){
  var mobile = layui.mobile
  ,layim = mobile.layim
  ,layer = mobile.layer;
  var autoReplay = [
    '您好,我現在有事不在,一會再和您聯系。',
    '你沒發錯吧?face[微笑] ',
    '洗澡中,請勿打擾,偷窺請購票,個體四十,團體八折,訂票電話:一般人我不告訴他!face[哈哈] ',
    '你好,我是主人的美女秘書,有什么事就跟我說吧,等他回來我會轉告他的。face[心] face[心] face[心] ',
    'face[威武] face[威武] face[威武] face[威武] ',
    '你要和我說話?你真的要和我說話?你確定自己想說嗎?你一定非說不可嗎?那你說吧,這是自動回復。',
    'face[黑線]  你慢慢說,別急……',
    '(*^__^*) face[嘻嘻] ,是賢心嗎?'
  ];
  var config = {
      //上傳圖片接口
      uploadImage: {
          url: '/Ashx/ImageUpDown.ashx' //(返回的數據格式見下文)
        , type: 'post' //默認post
      }
      //上傳文件接口
  , uploadFile: {
      url: '/Ashx/FileUpDown.ashx' //(返回的數據格式見下文)
    , type: 'post' //默認post
  }

      //,brief: true

  , init: {
      //我的信息
  }
      //擴展聊天面板工具欄
  //, tool: [{
  //    alias: 'code'
  //  , title: '代碼'
  //  , iconUnicode: '&#xe64e;'
  //}
  //]

      //擴展更多列表
  , moreList: [{
      alias: 'find'
    , title: '發現'
    , iconUnicode: '&#xe628;' //圖標字體的unicode,可不填
    , iconClass: '' //圖標字體的class類名
  }, {
      alias: 'share'
    , title: '分享與邀請'
    , iconUnicode: '&#xe641;' //圖標字體的unicode,可不填
    , iconClass: '' //圖標字體的class類名
  }]

      //,tabIndex: 1 //用戶設定初始打開的Tab項下標
      //,isNewFriend: false //是否開啟“新的朋友”
      , isgroup: true //是否開啟“群聊”
      , maxLength:1000000
      //,chatTitleColor: '#c00' //頂部Bar顏色
      //,title: 'LayIM' //應用名,默認:我的IM
  }
  //創建一個會話
  /*
  layim.chat({
    id: 111111
    ,name: '許閑心'
    ,type: 'kefu' //friend、group等字符,如果是group,則創建的是群聊
    ,avatar: 'http://tp1.sinaimg.cn/1571889140/180/40030060651/1'
  });
  */


  //監聽點擊“新的朋友”
  layim.on('newFriend', function(){
    layim.panel({
      title: '新的朋友' //標題
      ,tpl: '<div style="padding: 10px;">自定義模版,后期接入使用</div>' //模版
      ,data: { //數據
        test: '么么噠'
      }
    });
  });

  //查看聊天信息
  layim.on('detail', function(data){
    //console.log(data); //獲取當前會話對象
    layim.panel({
      title: data.name + ' 聊天信息' //標題
      , tpl: '<div style="padding: 10px;">自定義模版,自定義模版,后期接入使用</div>' //模版
      ,data: { //數據
        test: '么么噠'
      }
    });
  });

  //監聽點擊更多列表
  layim.on('moreList', function(obj){
    switch(obj.alias){
      case 'find':
        layer.msg('自定義發現動作');

        //模擬標記“發現新動態”為已讀
        layim.showNew('More', false);
        layim.showNew('find', false);
      break;
      case 'share':
        layim.panel({
          title: '邀請好友' //標題
          , tpl: '<div style="padding: 10px;">自定義模版,后期接入使用</div>' //模版
          ,data: { //數據
            test: '么么噠'
          }
        });
      break;
    }
  });

  //監聽返回
  layim.on('back', function(){
    //如果你只是彈出一個會話界面(不顯示主面板),那么可通過監聽返回,跳轉到上一頁面,如:history.back();
  });

  //監聽自定義工具欄點擊,以添加代碼為例
  //layim.on('tool(code)', function(insert, send){
  //  insert('[pre class=layui-code]123[/pre]'); //將內容插入到編輯器
  //  send();
  //});

  //監聽發送消息
  layim.on('sendMessage', function(data){
      var To = data.to;
      var mine=data.mine;
      console.log("偵察數據",data);
      if (To.type == "friend") {
          chathub.invoke("SendSingle", data);
      }
      else {
          chathub.invoke("Send", data);
      }
  });

        chathub.on("SendAsync" , function (data) {
        console.log("接受的數據",data);
        layim.getMessage(data);
         })
        chathub.on("addNewMessageToPage" , function (data) {
        config.init = data;
        layim.config(config);
        })
        chathub.on("newUser",function (res) {
        //監聽添加列表的socket事件,假設你服務端emit的事件名為:addList
        //socket.onmessage = function (res) {
        //if (res.emit === 'addList') {
        console.log("執行了自動添加");
        res.type = 'friend';
        res.groupid = 1;
        var nihao={
            type: 'friend' //列表類型,只支持friend和group兩種
            , avatar: "http://tvax1.sinaimg.cn/crop.0.0.300.300.180/006Iv8Wjly8ff7ghbigcij308c08ct8i.jpg" //好友頭像
            , username: '沖田杏梨' //好友昵稱
            , groupid: 1 //所在的分組id
            , id: "1233333312121212" //好友id
            ,sign: "本人沖田杏梨將結束的工作" //好友簽名
        }
        layim.addList(res);
        })
        chathub.on("RemoveUser",function (res) {
        console.log("執行了自動刪除");
        res.type= "friend";
        res.groupid = 1;
        console.log(res);
        layim.removeList(res);
    })

  //監聽查看更多記錄
  layim.on('chatlog', function(data, ul){
    console.log(data);
    layim.panel({
      title: '與 '+ data.name +' 的聊天記錄' //標題
      ,tpl: '<div style="padding: 10px;">這里是模版,{{d.data.test}}</div>' //模版
      ,data: { //數據
        test: 'Hello'
      }
    });
  });
  layim.on('chatChange', function (data) {
      console.log("查詢窗口",data);
  });
  //模擬"更多"有新動態
  layim.showNew('More', true);
  layim.showNew('find', true);
});
    </script>
</body>
</html>

這就是一個完整的案例可以運行的,下一節介紹如何寫一個簡單的signalr在小程序上運行的前端庫。


免責聲明!

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



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