亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于自定義token消息通知系統(tǒng)的設(shè)計與實現(xiàn)

        2020-08-26 07:46:55李毓麗陳泰宏
        電腦知識與技術(shù) 2020年20期

        李毓麗 陳泰宏

        摘要:為了提供給Web應(yīng)用以及Web開發(fā)者一種即時消息通知的解決方案,該設(shè)計主要以當(dāng)下流行的vuejs+Laravel+Mysql的技術(shù)組合方式,將前后端完全分離,降低開發(fā)的耦合性,有利于多階段的部署。并在此基礎(chǔ)上,白定義了一套令牌校驗機制以及利用swoole下的websocket接口實現(xiàn)消息通知功能,并且使用redis提高性能。

        關(guān)鍵詞:redis;websocket;自定義token;消息通知

        中圖分類號:TP311 文獻標(biāo)識碼:A

        文章編號:1009-3044(2020)20-0084-03

        1背景

        一個成熟的Web應(yīng)用必定少不了消息通知。例如商城中的到貨提醒功能,又如社交類型的網(wǎng)站,當(dāng)用戶A關(guān)注了用戶B,或者用戶C收藏了用戶D的話題,系統(tǒng)會定時發(fā)送更新的消息,去提醒對應(yīng)的用戶,所以,消息通知在當(dāng)下的WEB應(yīng)用中是非常重要的組成部分。

        2消息通知系統(tǒng)的設(shè)計

        消息通知系統(tǒng)是以用戶為單位來進行實現(xiàn),主要的技術(shù)棧為前端采用vue2.x,利用vue-cli創(chuàng)建項目,是一個單頁Web應(yīng)用,也就是我們說的SPA應(yīng)用。SPA應(yīng)用有許多的優(yōu)點,良好的交互體驗,用戶不需要頻繁的刷新頁面,通過Ajax從后臺瀆取數(shù)據(jù),利用vuex對數(shù)據(jù)進行管理。良好的前后端分離開發(fā)方式,讓單頁Web應(yīng)用可以和RESTful規(guī)約一起使用,通過RESTAPI提供接口數(shù)據(jù),并使用Ajax獲取數(shù)據(jù),這樣有助于分離客戶端和服務(wù)器端工作。在客戶端也可以分解為靜態(tài)頁面和頁面數(shù)據(jù)響應(yīng)兩個部分。最重要的是可以減輕服務(wù)器壓力,服務(wù)器只需要傳輸數(shù)據(jù)以及對一些存在安全隱患的數(shù)據(jù)進行驗證,不用管展示邏輯和頁面合成,吞吐能力會提高幾倍。但SPA單頁應(yīng)用也有一個比較大的缺點,就是SEO難度較高,所以在優(yōu)化期間會將頁面修改成服務(wù)器渲染的方式。

        后端采用的是PHP的框架Laravel,Laravel框架提供了許多軟件包,Laravel有一個好處就是倉庫非常多,加上有compos-er這一包管理器,使得其拓展性非常大。包括前端的一些組件包以及后臺的一些插件。由于我們采用的是前后端完全分離這一模式,會存在跨域問題,因此使用了laravel-cors這一插件包,解決跨域問題。

        根據(jù)需求,主要分為三部分,第一部分是用戶的登錄機制的實現(xiàn)。登錄采用前后分離的方式,這就需要令牌token的驗證,利用自定義實現(xiàn)的令牌機制,在登錄注冊這一功能上,根據(jù)OAUTH2.0協(xié)議,對用戶的登錄進行加密傳遞,通過用戶提供的用戶名密碼認證成功后,傳遞回來的access_token去獲取用戶數(shù)據(jù)。同時,還集成了短信登錄(阿里云短信接口)和微博登錄(微博開放平臺),方便用戶登錄,更好的拓展用戶量。

        第二部分是基于用戶登錄完成后的消息通知系統(tǒng),當(dāng)用戶登錄成功后,系統(tǒng)會自動連接上消息系統(tǒng),本部分的功能基于PHP異步框架swoole的實現(xiàn),通過swoole底層的封裝,達成對websocket協(xié)議的支持,從而使得用戶能夠作為長鏈接穩(wěn)定的接受系統(tǒng)通知消息。

        第三部分是基于Redis的以用戶為單位的域分離隊列消息推送。消息通知系統(tǒng)中少不了訂閱推送的功能,當(dāng)系統(tǒng)中的管理員,想給所有的用戶推送一條消息,假設(shè)平臺有10萬個用戶,如果按照原來的思路來實現(xiàn),那么就意味著每向所有用戶推送一條消息,則會通過消息表,向消息表中增加10萬條數(shù)據(jù),這樣做無疑會對數(shù)據(jù)庫的性能造成非常大的影響,會對服務(wù)器造成很大的壓力。而利用redis,則可以實現(xiàn)只插入一條數(shù)據(jù),通知所有用戶,并對用戶的其他消息不造成影響。

        3基于JWT標(biāo)準(zhǔn)與HMACSHA256+base64加密規(guī)則實現(xiàn)的自定義token機制

        Laravel框架白帶了一個實現(xiàn)OAUTH2.0協(xié)議和JWT標(biāo)準(zhǔn)的擴展包,名為Laravel-passport,該擴展包將token和Refresh-Token存于數(shù)據(jù)庫。并且安全性等各方面也已經(jīng)做得比較完善,但是缺點也很明顯,復(fù)雜的實現(xiàn)邏輯,繁重的trait,還有麻煩的將token記錄到數(shù)據(jù)庫(這樣無異于session)這些特點,都使得這個擴展包性能變得非常緩慢,并且很明顯,擴展性以及對外友好性不強,耦合性太高(只適用于Laravel框架)。因此實現(xiàn)一個自定義的token機制。

        3.1基于JWT標(biāo)準(zhǔn)的token定義

        根據(jù)JWT標(biāo)準(zhǔn),token被拆分為三部分:頭部、載荷、簽名。頭部中存著實現(xiàn)簽名的算法規(guī)則,以及實現(xiàn)方式,如下面代碼所示:

        private statiC $header= array(

        'alg'=>'HS256',//生成signature的算法

        'typ'=>'JWT'//類型

        );

        payload主要存著我們需要的數(shù)據(jù)內(nèi)容,叫作jwt載荷,需要幾個基本的字段,用于在后期的解析中使用,其中包括用戶idtoken的頒發(fā)時間和過期時間,以及jti(該token的唯一標(biāo)識)等。payload是token中最主要的部分。下面是定義access_token和refresh_token的payload的實現(xiàn)。

        accesstoken:

        $data= array(

        'iss'=>self::loadConf($iss)['secretuser'],//該JWT的簽發(fā)者

        'iat'=> time(),//簽發(fā)時間

        'exp'=> time()+ $exp,//過期時間

        'nbf'=> time0+ 10,//該時間之前不接收處理該Token

        'uid'=>$uid.

        'type'=>'access',

        'refresh_id'=>$refresh_id,

        'jti'=> $jti//該token的id);

        refresh_token:

        $data= array(

        'iss'=>self::loadConf($iss)['secret_user'],//該JWT的簽發(fā)者

        'iat'=> time(),//簽發(fā)時間

        'exp'=> time()+ $exp,//過期時間

        'nbf'=> time()+ 60,//該時間之前不接收處理該Token

        'uid'=>$uid.

        'type'=>'refresh',

        'jti'=>$jti);

        第三部分是簽名部分,簽名部分是由一個白定義的隨機字符串組成的key,由這個key,對前面兩部分進行base64編碼和HMACSHA256加密形成簽名。這一部分是確保token安全性的必須內(nèi)容。生成token代碼:

        public static function getToken(array $payload, string $key)

        {if(is_array($payload)){

        $base64header=self:: base64UrIEncode(json_encode(self::$header, JSON_UNESCAPED_UNICODE));

        $base64payload=self:: base64UrlEncode(json_encode($payload, JSON_UNESCAPED_UNICODE));

        retum $base64header.'.'.$base64payload.'.'.self::signature($base64header.'.'.$base64payload, $key, self'::$header['alg']);

        }else{

        return false;

        }}

        當(dāng)生成token之后,再通過指定的key,將token解析,當(dāng)校對無誤后,解析出完整的載荷內(nèi)容,當(dāng)解析正確,中間件將認為這是一個允許訪問的請求,則可以進入控制器,執(zhí)行相應(yīng)的功能邏輯。為了給不同的用戶定制不同的配置,例如管理員to-ken和用戶token的secret key肯定不能相同,或者過期時間等配置,所以會獨立出來,以使用者為單位進行配置,配置文件如下所示:

        /*用戶*/

        'user'=>[

        'secret_key'=>'vhjcUExrBL5q6kWW"',//Str:: random()生成

        'secret user'=>'Jasper_User',

        'access_token_expire_time'=>7200.//access_token過期時間

        'ref'resh_token_expire_time'=>86400.//refresh_token過期時間

        ],

        /*管理員*/

        'admin'=>[

        'seCret_key'=>'IlzzMTZAX6tycbkM',//Str::random()生成

        'seCret user'=>'Jasper_Admin',

        'accesstoken_expiretime'=>84600,//access_token過期時間

        'refresh_token_expire_time'=>86400.//refresh_token過期時間

        ],

        對前臺用戶的中間件攔截請求如下面代碼所示,對于管理員的攔截也是類似的寫法,開發(fā)者只需要簡單的修改一下使用者的身份并且在配置文件配置好,則可以實現(xiàn)不同的秘鑰。這樣很好的解決了耦合性的問題,使開發(fā)者很方便的就能夠使用不同的機制開發(fā)其他不同類型的功能。

        $token= SerAuth::getFinalToken($Auth);

        if (!$token) return response(retumAPI(6000));

        $result=SerAuth::verifyToken($token);

        if(! $result['token'])

        retum resp.nse(returnAPl($result['code']));

        $info= $result['payload']['uid'];

        $request->payload= $info;

        return $next($request);

        4基于websocket協(xié)議和swoole的消息通知系統(tǒng)實現(xiàn)

        系統(tǒng)的實現(xiàn)較為復(fù)雜,采用點對多的方式。管理員給用戶發(fā)送一條消息,消息將會通過某個控制器的方法,調(diào)用封裝好的發(fā)送消息的service方法,將消息發(fā)送websocket服務(wù)器。該ServiCe作為一個短暫的客戶端,將信息轉(zhuǎn)發(fā)給webs。cket服務(wù)器之后,立即斷開,因為該連接不需要進行長連接占用資源,它只負責(zé)講消息發(fā)送到服務(wù)器。再由已經(jīng)連接上websocket的前臺客戶端,接收服務(wù)器所發(fā)送的消息。

        獲取信息的內(nèi)容,并將信息入庫。然后利用composer中的websocket建立一個短鏈接客戶端,鏈接到服務(wù)器,將消息通知給對應(yīng)的用戶。當(dāng)管理員發(fā)送消息請求時候,需要將消息的主體入庫,以此來達到同步數(shù)據(jù)的目的。同步數(shù)據(jù)是為了準(zhǔn)確的提高用戶了解未讀信息的數(shù)量。當(dāng)管理員發(fā)起一條消息,消息表入庫,未讀消息則加l,在客戶端的store倉庫中,會將用戶顯示的未讀消息數(shù)量增1,所以當(dāng)用戶刷新或者退出登錄狀態(tài)時,即使收不到及時信息,但是消息表中依然有記錄,等待用戶登錄的時候,依舊能夠看到所有的信息。這就完成了一整套的消息通知流程。具體如下圖1所示。

        5基于Redis緩存的數(shù)據(jù)讀取,減少直接讀取數(shù)據(jù)庫以及對數(shù)據(jù)庫的操作

        本系統(tǒng)是基于websocket下的swoole框架來完成業(yè)務(wù),配合Mysql數(shù)據(jù)庫的消息表進行消息的存取。其中的一個業(yè)務(wù)是管理員需要向平臺的所有用戶推送某一消息,例如商品上線通知等系統(tǒng)消息。那么,如果平臺有十萬甚至百萬個用戶,推送的數(shù)據(jù)量存入消息表就非常大。如果每發(fā)送一條消息,消息表都需要增加10萬條數(shù)據(jù),那么這樣對數(shù)據(jù)庫性能和服務(wù)器要求無疑是非常大的。因此,我們可以通過緩存來實現(xiàn)全部推送。管理員向所有用戶推送信息,只需要在數(shù)據(jù)庫中加入一個字段“is_all",來判斷該消息是否是所有用戶的消息即可。在查詢某個用戶的消息時,會有兩部分,一是擁有自己的消息的數(shù)據(jù),二是帶有“is_all”字段的消息。當(dāng)用戶已讀消息時,正常消息會修改“is_read”字段標(biāo)識為已讀,而對于“is_all,類型的消息,為了避免其他用戶的消息受到影響,則會需要用緩存將每個用戶的已讀消息存人,在數(shù)據(jù)查詢時忽略這些內(nèi)容,即可完成已讀未讀區(qū)分。刪除功能也是如此。

        經(jīng)過多次的測試發(fā)現(xiàn),這種消息通知入庫的方式可行,并可以極大程度的避免了數(shù)據(jù)庫中數(shù)據(jù)的冗余性,有利于系統(tǒng)高效的運行,減少了頻繁入庫的操作。

        6結(jié)束語

        論文主要論述了基于白定義token以用戶為單位的消息通知系統(tǒng)的設(shè)計與實現(xiàn)。重點闡述自定義token機制的實現(xiàn),包括頭部、載荷、簽名。實現(xiàn)基于websocket協(xié)議和swoole的消息通知流程,以及消息通知入庫的方式,提高系統(tǒng)的性能和運行效率,

        參考文獻:

        [1] Vue CLI[EB/OLl.[2019-12-20l.https://cli.vuejs.org/zh/guitle/.

        [2] larave16.0中文文檔[EB/OL].[2019-12-20].https://leamku.com/docs/laraveU6.0.

        [3] Vanessa Wang.HTML5 WebSocket指南2018[M].北京:機械工業(yè)出版社,2014: 21-250.

        【通聯(lián)編輯:謝媛媛】

        收稿日期:2020-05-08

        作者簡介:李毓麗( 1980-),女,廣東普寧人,副教授,碩士,主要從事網(wǎng)絡(luò)技術(shù)、網(wǎng)絡(luò)編程方向的教學(xué)研究。

        99精品欧美一区二区三区| 久久久国产精品三级av| 美女免费视频观看网址| 人人鲁人人莫人人爱精品| 中国丰满熟妇xxxx| 国产精品久久久久久久| 色婷婷久久一区二区三区麻豆 | 免费人成网站在线观看欧美| 大地资源在线播放观看mv| 日韩国产精品一本一区馆/在线| 欧美日韩国产在线人成dvd| 日本一区二区三区高清视| 国产精品186在线观看在线播放| 精品亚洲欧美无人区乱码| 女人的天堂av免费看| 亚洲无人区乱码中文字幕动画| 好大好湿好硬顶到了好爽视频| 97精品依人久久久大香线蕉97| 国产成人亚洲合集青青草原精品| 日本一区二区三区一级片| 亚洲av综合色区无码专区桃色| 激情内射亚州一区二区三区爱妻| 亚洲国产精品中文字幕日韩| 亚洲中文中文字幕乱码| 美女不带套日出白浆免费视频| 99久久久无码国产精品免费砚床| 久久精品国产88久久综合| 国产一区二区三区的区| 男人边做边吃奶头视频| 久久精品国产精品青草色艺| 亚洲精品123区在线观看| 精品人妻一区二区视频| 人妻少妇被粗大爽.9797pw| 又色又爽又黄又硬的视频免费观看 | 中国免费看的片| 18禁高潮出水呻吟娇喘蜜芽 | 三级黄片一区二区三区| 69精品国产乱码久久久| 67194熟妇人妻欧美日韩| 99热精品成人免费观看| 国产一区不卡视频在线|