最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

實(shí)際項(xiàng)目講解 Signalr(.net core3.x)使用

2020-02-06 16:22 作者:Tuple_元組  | 我要投稿

最近認(rèn)真研究了一個(gè)微軟最新的.net core3.x版本中的signalr技術(shù),并使用之開(kāi)發(fā)了一個(gè)相對(duì)穩(wěn)定的聊天系統(tǒng)。在此作一些記錄,希望能給需要的同志作一些有益的提醒。

一、系統(tǒng)功能界面


聊天系統(tǒng)界面,類似微信顯示方式

、主要功能代碼

1.用戶登陸(Cookie方式)

? ?public IActionResult OnPost(string InputTime, string UserId, string Password)
? ? ? ? {

? ? ? ? ? ? if (!string.IsNullOrWhiteSpace(UserId) && !string.IsNullOrWhiteSpace(Password))

? ? ? ? ? ? {

? ? ? ? ? ? ? ? string tKey = (DateTime.Parse(InputTime).Second - 2).ToString();

? ? ? ? ? ? ? ? ModelUser user = GlobalVars.AllChatUsers.Where(e => e.Id.Equals(UserId) && (e.Pwd + tKey).Equals(Password)).FirstOrDefault();

? ? ? ? ? ? ? ? if (user != null)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? Claim[] Claims = new Claim[] { new Claim(ClaimTypes.Name, user.Id) };

? ? ? ? ? ? ? ? ? ? ClaimsIdentity ClaimsIdentity = new ClaimsIdentity(Claims, CookieAuthenticationDefaults.AuthenticationScheme);

? ? ? ? ? ? ? ? ? ? ClaimsPrincipal LoginUser = new ClaimsPrincipal(ClaimsIdentity);

? ? ? ? ? ? ? ? ? ? Task.Run(async () =>

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? //登錄用戶

? ? ? ? ? ? ? ? ? ? ? ? await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, LoginUser);

? ? ? ? ? ? ? ? ? ? ?}).Wait();

? ? ? ? ? ? ? ? ? ?return RedirectToPage("./WebChat", new { Login = "First" });

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ?//"用戶名或密碼錯(cuò)誤!";

? ? ? ? ? ? return Page();
? ? ? ? }

2.客戶端連接服務(wù)器代碼

function ConnectionStart() {

? ? if (g_ReconnectCount >= g_ReconnectMaxTimes) {

? ? ? ? AddMsgToChatList.AddMessage('<span style="color:red">已重連 ' + g_ReconnectCount.toString() + ' 次,仍無(wú)法連接。請(qǐng)檢查網(wǎng)絡(luò),然后刷新重試!</span>');

? ? ? ? return;

? ? }

? ? connection.start().then(function () {

? ? ? ? g_divInputMsg.setInputState(true);

? ? ? ? //connection.state === signalR.HubConnectionState.Connected

? ? ? ? //AddMsgToChatList.AddMessage('<span style="color:red">已連接到服務(wù)器</span>');

? ? }).catch(function (err) {

? ? ? ? //connection.state === signalR.HubConnectionState.Disconnecte

? ? ? ? //AddMsgToChatList.AddMessage('<span style="color:red">連接已斷開(kāi),正在重連....(' + g_ReconnectCount.toString() + ')</span>');

? ? ? ? g_ReconnectCount++;

? ? ? ? setTimeout(() => ConnectionStart(), 500);

? ? });

}

//首次連接服務(wù)器。

ConnectionStart();

3.?客戶端發(fā)信息到服務(wù)器(使用流傳輸方式,帶發(fā)送進(jìn)度顯示,以防止客戶端發(fā)大圖時(shí)會(huì)卡死或無(wú)法發(fā)送的現(xiàn)象)

客戶端主要代碼(Javascript):

async function sendMsgToSever(willSendMsg, processElement) {

? ? processElement.innerHTML = '已發(fā)送(0/' + willSendMsg.length + ')';

? ? //客戶端到服務(wù)器的流式處理

? ? var startIndex = 0;

? ? var stopIndex = 0;

? ? var fixLength = 1024 * 20; //此大小影響數(shù)據(jù)發(fā)送速度。4096=8407,5120=6714,10240=3348,20480=1882

? ? var msgSubStr = '';

? ? //var beginTime = (new Date()).valueOf();

? ? console.log(new Date().toDateString)

? ? const subject = new signalR.Subject();

? ? connection.send("UploadStream", subject);

? ? if (willSendMsg.length <= fixLength) { stopIndex = willSendMsg.length; } else { stopIndex = fixLength; }

? ? var sendFun = function () {

? ? ? ? if (stopIndex <= willSendMsg.length) {

? ? ? ? ? ? msgSubStr = willSendMsg.substring(startIndex, stopIndex);

? ? ? ? ? ? subject.next(msgSubStr);

? ? ? ? ? ? processElement.innerHTML = '已發(fā)送(' + stopIndex.toString() + '/' + willSendMsg.length + ')';? ?//顯示發(fā)送到服務(wù)器的進(jìn)度

? ? ? ? ? ? startIndex = stopIndex;

? ? ? ? ? ? if (willSendMsg.length === stopIndex) {

? ? ? ? ? ? ? ? subject.complete();

? ? ? ? ? ? ? ? //var endTime = (new Date()).valueOf();

? ? ? ? ? ? ? ? //console.log(fixLength.toString() + '=' + (endTime - beginTime).toString());

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }

? ? ? ? ? ? if (willSendMsg.length >= (stopIndex + fixLength)) { stopIndex += fixLength; } else { stopIndex += willSendMsg.length - stopIndex; }

? ? ? ? }

? ? ? ? window.setTimeout(sendFun, 0);

? ? }

? ? sendFun();

}

服務(wù)器端主要代碼(C#):

?public async Task UploadStream(IAsyncEnumerable<string> stream)

? ? ? ? {

? ? ? ? ? ? //接收客戶端發(fā)來(lái)的信息

? ? ? ? ? ? System.Text.StringBuilder ClientNewMsg = new System.Text.StringBuilder();

? ? ? ? ? ? await foreach (var item in stream)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? ClientNewMsg.Append(item);

? ? ? ? ? ? }

? ? ? ? ? ? string message = ClientNewMsg.ToString();

? ? ? ? ? ? //發(fā)給指定用戶

? ? ? ? ? ? await Clients.Client(RUser.ConnectionId).SendAsync("ReceiveMessage", message);

? ? ? ? }

4.服務(wù)器端推送信息到客戶端

客戶端主要代碼(Javascript):

connection.on("ReceiveMessage", async function (MsgObj) {

? ? webChatLock.Reset();//鎖屏重計(jì)時(shí)

? ? if (g_PlaySound) {

? ? ? ? var SoundFile = "/images/dingdong.wav";

? ? ? ? var SoundObj = new Audio(SoundFile);

? ? ? ? SoundObj.play();

? ? }

? ? var MsgJson = JSON.parse(MsgObj);

? ? //....進(jìn)一步處理收到的數(shù)據(jù)

? ? }

服務(wù)器端主要代碼(C#):

? ??await Clients.Client(RUser.ConnectionId).SendAsync("ReceiveMessage", message);

5.需要注意的幾個(gè)問(wèn)題。

  • js讀取圖片內(nèi)容生成DataBase64?格式數(shù)據(jù)時(shí),<input type="file"/> 控件不能僅使用聲明,而必須添加到頁(yè)面上,否則蘋(píng)果手機(jī) safari 瀏覽器可以打開(kāi)文件選擇框,但將無(wú)應(yīng)響應(yīng)控件的 change事件。

  • 更新頁(yè)面數(shù)據(jù)顯示進(jìn)度時(shí),需使用?window.setTimeout(funname,0),在funname()中發(fā)送并更新頁(yè)度進(jìn)度值,否則將看不到數(shù)據(jù)變化。

  • 在處理用戶的離線消息時(shí),應(yīng)使用線程安全的ConcurrentDictionary<string, ModeMsgServer> NeedSendMsgs 等類。

  • 在收到或發(fā)送信息時(shí),讓聊天窗口自動(dòng)滾動(dòng)到最底部,使用?DivChatElement.scrollIntoView(false);代碼,需注意的是,信息中有圖片,則上述代碼應(yīng)在圖片的 load 事件中執(zhí)行。

  • 采用客戶端收到服務(wù)器信息后立即回調(diào)signalr的Hub中指定方法的方式,以便使服務(wù)器得以確認(rèn)客戶端已收到信息,從而將已發(fā)送的信息刪除(否則將適時(shí)重新發(fā)送或在下次該用戶登陸時(shí)再發(fā)送,以確保用戶收到該信息)。

  • 關(guān)于客戶端與服務(wù)器端“心跳”配置。(注意客戶端與服務(wù)器端的時(shí)間要相匹配)

服務(wù)器端(Startup.cs):? ?

services.AddSignalR(options =>

? ? ? ? ? ? {

? ? ? ? ? ? ? ? //客戶端發(fā)保持連接請(qǐng)求到服務(wù)端最長(zhǎng)間隔,默認(rèn)30秒

? ? ? ? ? ? ? ? options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);

? ? ? ? ? ? ? ? //服務(wù)端發(fā)保持連接請(qǐng)求到客戶端間隔,默認(rèn)15秒

? ? ? ? ? ? ? ? options.KeepAliveInterval = TimeSpan.FromSeconds(15);

? ? ? ? ? ? ? ? options.EnableDetailedErrors = true;

? ? ? ? ? ? ? ? options.MaximumReceiveMessageSize = 1024 * 1024 * 1024;

? ? ? ? ? ? });

客戶端(js):

//設(shè)置連接對(duì)象的相關(guān)屬性

connection.serverTimeoutInMilliseconds = 30e3;? //等待服務(wù)器端發(fā)送過(guò)來(lái)的心跳包最長(zhǎng)等待時(shí)間30s(如該時(shí)間段時(shí)收到不服務(wù)器發(fā)送的“心跳”數(shù)據(jù),即認(rèn)為鏈接丟失)

connection.keepAliveIntervalInMilliseconds = 15e3; //客戶端向服務(wù)器發(fā)送心跳包頻率15s



實(shí)際項(xiàng)目講解 Signalr(.net core3.x)使用的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
新邵县| 金寨县| 唐海县| 会泽县| 共和县| 淮滨县| 泗阳县| 新巴尔虎左旗| 新民市| 荃湾区| 南通市| 巴里| 濉溪县| 万荣县| 黄大仙区| 宁德市| 富川| 彭阳县| 海晏县| 玉门市| 密云县| 富平县| 平邑县| 介休市| 邛崃市| 凉城县| 南丹县| 滦南县| 大港区| 汝州市| 兴海县| 米林县| 朔州市| 苍山县| 绍兴县| 衡阳市| 城固县| 莱西市| 大埔县| 思茅市| 本溪|