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在小程序上运行的前端库。

原文地址:https://www.cnblogs.com/aoximin/p/13228798.html