前言
在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: ''
//}
//]
//擴展更多列表
, moreList: [{
alias: 'find'
, title: '發現'
, iconUnicode: '' //圖標字體的unicode,可不填
, iconClass: '' //圖標字體的class類名
}, {
alias: 'share'
, title: '分享與邀請'
, iconUnicode: '' //圖標字體的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在小程序上運行的前端庫。