多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > [置頂] 由一次年會系統大戰所想到的。。。(1)

[置頂] 由一次年會系統大戰所想到的。。。(1)

來源:程序員人生   發布時間:2017-03-22 09:32:01 閱讀次數:3658次

上個月接到了我公司年會系統的需求,覺得做起來有些困難。后來硬著頭皮接下來了。年會1月6號順利舉行結束,整體上還算是成功,但是最后的搖1搖比賽出了些問題。在這里記錄下用到的技術,遇到的困難和選擇,和做的處理和不足。希望對大家有些參考。

先上1點結論和感想

1.做1個系統,需要權衡的維度,有以下幾個:
這里寫圖片描述
這就好比經典的CAP理論,魚和熊掌不可兼得。這里尋求了時間(只有兩周多的開發時間),本錢(實際上不應當過分緊縮本錢),功能(做全所有功能),放低了安全與周密的要求(例如消息傳遞沒有加密,傳遞的消息沒有蓋時間戳驗證流程,沒有完全的會話保持與權限控制等等),而且把代碼放到了GitHub上。
對1個針對普通大眾的年會,這么做多是沒問題的。但是對1個純程序員的年會,這么做就難免出問題(我們現場系統遭到了js注入,XSS注入,SQL注入還有指令注入攻擊。我們現場改代碼熱部署)。
現在回想,應當把1些功能做的更周密些,不應當過分緊縮本錢(其實就是多買兩臺服務器的事。。。)

2.對你做的系統,觸及到現場屏幕視覺設計的,1定要提早摹擬下視覺匹配

3.之前對Websocket的理解有誤,只在,對需要單向推送到客戶端(手機閱讀器)上的消息,應當都用Websocket,而不是采取客戶端輪詢。輪詢對服務器消耗太大。然后,其實更多情形應當用SSE

4. 對產品設計上,可能需要改變下自己程序員的思惟。程序員都有點because we can的思惟,這其實不都是缺點。但是把這個思惟用在設計產品上就掛了。這里的例子就是搖1搖抽獎。這里我們沒用微信搖1搖的功能,而是用js監控陀螺儀移動而做的搖1搖,顯示的次數其實不是準確的你搖動的次數,可能會有很大偏差。但是我們把這個數字展現出來了,并且沒做說明,讓很多用戶認為這個次數不公正,是我們私下做了手腳。

5.流程太繁瑣,走簡單流程搶時間難免出問題。目前,內部生產上線流程繁瑣而且時間長。我們如果采取的話,全部開發時間都得用來走上線流程。所以,沒采取公司資源,自己購買的騰訊云部署的利用,最后安全性出問題。如果走公司內部流程做足檢查就不會出這些問題,但是時間上不允許。估計等公司變革完,這個情況會改良很多。

6. 彈幕做了服務降級,其實搖1搖那里也應當做服務降級

1. 需求的確立與任務的分配

剛開始,接到的需求主要有這幾個模塊:微信簽到上墻,CP簽到抽獎,彈幕上墻,節目打賞,抽獎,搖1搖比賽還有紅包鏈接展現。時間比較緊,基本上只有兩周多的時間去開發。
團隊里面算上我1共4人,都是新人(我是最老的員工,剛畢業1.5年。。)。劃分了下任務,A同學負責簽到前端,抽獎前后端,B同學負責節目管理打賞前端,搖1搖前端,C同學負責節目管理打賞前端,紅包鏈接展現前后端,CP簽到抽獎,我負責微信簽到后端,微信接口調試和彈幕上前前后端。

2. 微信簽到開發

整體邏輯架構設計:
這里寫圖片描述
微信開發回比較容易,文檔全,但是文檔有的更新不夠新,而且管理界面有時讓人第1次使用摸不著頭腦。不過嘗試出來如何配置后,還比較容易的。
首先,你得先去申請個微信公眾號,我們這里要用的微信功能有:網頁服務中的網頁賬號服務,微信JSAPI。搖1搖我們沒用微信的搖1搖功能,用的是js的振東事件。對微信簽到,我們只用到網頁服務中的網頁賬號服務,其他的其他功能會用到。
對公眾號,如果需要網頁賬號服務,則需要你的公眾號經過認證。搖1搖需要其他資質認證,比較麻煩所以我沒用。
對測試,可以先申請個微信測試號:http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
申請好后,我們看到:
這里寫圖片描述

2.1. 接口配置信息驗證

這個是為了測試你的服務器是不是認證良好,并且信任這臺服務器并把消息轉發給這臺服務器。在配置時,微佩服務器會發1條消息到你配置的服務器,如果返回的結果正確,則配置成功(這里可以填寫域名或IP,正式的公眾號必須用域名,而且這個域名是ICP備案過的)。由于我們不做消息處理,而且我們只想簡單的啟用這個測試號,所以這里,我們只寫了1個簡單的直接返回結果的認證方法,代碼以下:

@ResponseBody
@RequestMapping(value = "/weixin/message", method = RequestMethod.GET)
public String getWXUserInfo(@RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce, @RequestParam("echostr") String echostr) {
    //加解密省略。。。直接返回成功
    return echostr;
}

2.2. 網頁服務認證

首先先要配置:
這里寫圖片描述
一樣的,這里可以填寫域名或IP,正式的公眾號必須用域名,而且這個域名是ICP備案過的
測試號信息中的appID還有appSecret是你的app開放認證信息的證書。
1般的,開放平臺都是利用OAuth2.0協議:
這里寫圖片描述

對微信,流程以下:
這里寫圖片描述

第1步:拼接自己的連接:

appId wx0c7b8ab55037d5ca
scope 利用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲得用戶openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。并且,即便在未關注的情況下,只要用戶授權,也能獲得其信息),這里我們需要用snsapi_userinfo
response_type 只能填寫code
state 重定向到你的頁面時會帶上這個state參數,沒用的話隨意填寫就好了
redirect_uri 域名1定要和你配置的1樣,否則會報redirect_uri毛病,需要url編碼

跳轉的鏈接需要接收兩個參數,1個是code,1個是state;假定我們這里跳轉的地址為“/weixin/login”,則地址路徑為:http://127.0.0.1/weixin/login,經過url編碼為:http%3A%2F%2F127.0.0.1%2Fweixin%2Flogin

所以,最后的連接為:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx0c7b8ab55037d5ca&redirect_uri=http%3A%2F%2F127.0.0.1%2Fweixin%2Flogin&response_type=code&scope=snsapi_base&state=123#wechat_redirect

通過這個鏈接開始調試你的公眾號。

建議用QQ閱讀器,這樣能調試微信的鏈接。

第2步,編寫微信返回類:

微信的所有返回返回信息都是json情勢的,如果參數有誤,返回的結果都包括errcode和errmsg,所以編寫微信返回基類:

public class BaseReturn implements Serializable {
    private int errcode;
    private String errmsg;

    public int getErrcode() {
        return errcode;
    }

    public void setErrcode(int errcode) {
        this.errcode = errcode;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }

    public boolean isSuccessful() {
        return this.errcode == 0;
    }
}

客戶端根據臨時令牌code從服務提供方那里獲得訪問令牌access token的返回的類以下:

public class UserAuthorizationReturn extends BaseReturn {
    private String access_token;//  網頁授權接口調用憑證
    private int expires_in;//access_token接口調用憑證超時時間,單位(秒)由于access_token具有較短的有效期,當access_token超時后,可使用refresh_token進行刷新,refresh_token具有較長的有效期(7天、30天、60天、90天),當refresh_token失效的后,需要用戶重新授權。
    private String refresh_token;// 用戶刷新access_token
    private String openid;//    用戶唯1標識,請注意,在未關注公眾號時,用戶訪問公眾號的網頁,也會產生1個用戶和公眾號唯1的OpenID
    private String scope;//用戶授權的作用域,使用逗號(,)分隔

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getRefresh_token() {
        return refresh_token;
    }

    public void setRefresh_token(String refresh_token) {
        this.refresh_token = refresh_token;
    }

    public int getExpires_in() {
        return expires_in;
    }

    public void setExpires_in(int expires_in) {
        this.expires_in = expires_in;
    }

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }

}

由于年會只有1個晚上,我們不用更新用戶信息,所以對這里的expires_in其實不做處理。
以后通過accessToken拿取用戶信息返回的類以下:

public class UserInfoReturn extends BaseReturn {
    private String openid;//用戶的唯1標識
    private String nickname;//用戶昵稱
    private int sex;//用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知
    private String province;//用戶個人資料填寫的省分
    private String city;//  普通用戶個人資料填寫的城市
    private String country;//國家,如中國為CN
    private String headimgurl;//用戶頭像,最后1個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空。若用戶更換頭像,原有頭像URL將失效。
    private String privilege;//用戶特權信息,json 數組,如微信沃卡用戶為(chinaunicom)
    private String unionid;//只有在用戶將公眾號綁定到微信開放平臺帳號后,才會出現該字段。

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getHeadimgurl() {
        return headimgurl;
    }

    public void setHeadimgurl(String headimgurl) {
        this.headimgurl = headimgurl;
    }

    public String getPrivilege() {
        return privilege;
    }

    public void setPrivilege(String privilege) {
        this.privilege = privilege;
    }

    public String getUnionid() {
        return unionid;
    }

    public void setUnionid(String unionid) {
        this.unionid = unionid;
    }

}

第3步,根據上面的流程,編寫下面代碼,拿取用戶信息:

@RequestMapping(value = "/weixin/login", method = RequestMethod.GET)
public String getWXUserInfo(@RequestParam("code") String code, HttpServletResponse response) {
    try {
        String s = httpRequest.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token",
                "appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code");
        UserAuthorizationReturn userAuthorizationReturn = JSON.parseObject(s, UserAuthorizationReturn.class);
        s = httpRequest.sendGet("https://api.weixin.qq.com/sns/userinfo",
                "access_token=" + userAuthorizationReturn.getAccess_token() + "&openid=" + userAuthorizationReturn.getOpenid() + "&lang=zh_CN");
        Integer userId = userService.isSignedByWxInfo(userAuthorizationReturn.getOpenid());
        log.info("微信返回:" + s);
        //以后代碼略
}

2.3. 登陸邏輯

可以參加晚會的人名單是固定的,除這些人,其他人不能參與晚會。我們先把所有的人名單導入到數據庫中。
我們使用工號姓名登陸。工號全是數字,有人有在工號前面加0的習慣,為了都能登錄,我們保存在數據庫中的類型是數字,前端傳輸過來的字符串會轉換成數字與數據庫中的比對。只有工號姓名匹配的用戶才能登陸系統。
對已授權的微信譽戶,如果登陸過的話,則不用再登陸1次。直接進入年會主界面。
用戶輸入工號姓名后,它的用戶信息會被保存到數據庫(包括工號姓名還有微信譽戶信息)中。由于微信信息中的openid是唯1的,所以根據這個是不是在數據庫中存在,判斷是不是是第1次登陸。

完全的代碼:

@RequestMapping(value = "/weixin/login", method = RequestMethod.GET)
    public String getWXUserInfo(@RequestParam("code") String code, HttpServletResponse response) {
        try {
            //根據code獲得accessToken
            String s = httpRequest.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token",
                    "appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code");
            UserAuthorizationReturn userAuthorizationReturn = JSON.parseObject(s, UserAuthorizationReturn.class);
            s = httpRequest.sendGet("https://api.weixin.qq.com/sns/userinfo",
                    "access_token=" + userAuthorizationReturn.getAccess_token() + "&openid=" + userAuthorizationReturn.getOpenid() + "&lang=zh_CN");
            Integer userId = userService.isSignedByWxInfo(userAuthorizationReturn.getOpenid());
            log.info("微信返回:" + s);
            if (userId != null) {            //已簽到
                CookiesUtil.addCookie(response, "userId", String.valueOf(userId), 86400);
                return "redirect:/frontend/main.html";
            } else {                  //未簽到
                CookiesUtil.addCookie(response, "userJson", URLEncoder.encode(s, "UTF⑻"), 86400);
                return "redirect:/frontend/login.html";
            }
        } catch (Exception e) {
            log.warn(ExceptionUtils.getStackTrace(e));
        }
        return "redirect:/frontend/404.html";
    }

這里我們偷懶了,并沒有嚴格的會話和登錄權限控制,只是做了簡單的cookie。面對都是程序員的晚會,不應當做這么簡單的登陸控制。

2.4. 簽到上墻Websocket

在用戶第1次成功登陸也就是簽到成功時,服務器需要將這個簽到消息推送給客戶端。這類單項推送的技術,有很多可以選擇:

  1. HTTP輪詢和長輪詢:最容易實現,但是比較繁瑣而且耗費服務器資源. 簡易輪詢由于其本身的缺點,其實不推薦使用。Comet 技術其實不是 HTML 5 標準的1部份,從兼容標準的角度動身,也不推薦使用。
  2. Websocket:全雙工協議,可以用。市面上所有閱讀器都支持,對Spring有很好的集成,但是是從Spring 4.0開始的,我們用的框架基于Spring 3.X,來不及升級。但是Tomcat 7.X有現成的websocket實現。WebSocket 規范和服務器推送技術都是 HTML 5 標準的組成部份,在主流閱讀器上都提供了原生的支持,是推薦使用的。
  3. SSE服務器發送事件:對簡單的服務器數據推送的場景,使用服務器推送(SSE技術)事件就足夠了。這個是最合適的,惋惜當時我不知道這個技術。可以參考:http://www.cnblogs.com/imstudy/p/5682555.html.

服務器通過Websocket通道,將人員簽到的信息推送至簽到墻頁面,這里我應用的是最簡單的tomcat 7的websocket實現。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 免费观看性欧美特黄 | 中国黄色网址大全 | 国产精品日韩欧美一区二区三区 | xxxxx日本护士xxxhd | 伊人网视频在线观看 | 2019最新中文字幕 | 日本一区二区三区在线网 | 九色中文| 国产精品视频国产永久视频 | 网站久久| 欧美性视频网站 | 最近的中文字幕在线国语 | a成人| 一级片欧美 | 在线亚洲精品国产成人二区 | 久久成人视 | 亚洲人成影院在线高清 | 国产欧美日韩亚洲 | 日本天堂在线 | 国产精品视频视频久久 | 中文字幕一区精品欧美 | 毛片影视| 国产自产c区 | 日本亚洲天堂 | 韩国精品一区二区久久 | 国产人成久久久精品 | 999精品视频在线观看 | 成人欧美一区二区三区视频xxx | 免费观看老外特级毛片 | 波多野结衣在线视频播放 | 亚洲第1页| 亚洲精品福利网站 | 欧美精品99久久久久久人 | 亚洲欧美日韩在线精品一区二区 | 欧美性猛交99久久久久99 | 一区二区三区免费视频 www | 免费看黄的网址 | 手机在线完整视频免费观看 | 国产性生活视频 | 精品久久久久久 | 青青草原亚洲视频 |