Android微信登錄、分享、支付

来源:http://www.cnblogs.com/yishaochu/archive/2017/09/16/7531638.html
-Advertisement-
Play Games

轉載需要著名出處: 之前寫過微信登錄分享支付第一版: 前言 大部分的app都有接入第三方sdk的需求。例如第三方登錄需要接入微信、QQ、微博。第三方支付需要接入微信、支付寶、銀聯。 這些我都有使用過,都有使用過他們的sdk,感覺最麻煩的就是微信,不能直接調試,得用正式的簽名進行簽名才能調試。還有他們 ...


轉載需要著名出處:

http://blog.csdn.net/lowprofile_coding/article/details/78004224

之前寫過微信登錄分享支付第一版:

http://blog.csdn.net/lowprofile_coding/article/details/48086381

前言

大部分的app都有接入第三方sdk的需求。例如第三方登錄需要接入微信、QQ、微博。第三方支付需要接入微信、支付寶、銀聯。

這些我都有使用過,都有使用過他們的sdk,感覺最麻煩的就是微信,不能直接調試,得用正式的簽名進行簽名才能調試。還有他們官方的demo也是跑不起來的,因為沒有簽名文件。需要註意的地方也很多。

代碼實現

微信sdk現在支持Android Studio線上引用了,之前都是添加jar的方法。需要訪問微信的介面獲取用戶信息,所以把我們之前封裝的okhttp也一起線上引用。okhttp需要在自定義的Application中初始化這個我就不貼代碼了。之前已經講過很多次。在app/build.gradle文件dependencies標簽中加入以下兩行代碼:

compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
compile 'com.ansen.http:okhttpencapsulation:1.0.1'

需要用到網路,所以在AndroidManifest.xml文件中加入網路許可權:

<uses-permission android:name="android.permission.INTERNET" />

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登錄之後信息在這裡顯示"/>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/tv_nickname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="昵稱:"/>

        <TextView
            android:id="@+id/tv_age"
            android:layout_below="@+id/tv_nickname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="年齡:"/>
    </RelativeLayout>

    <Button
        android:id="@+id/btn_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="微信登錄"/>

    <Button
        android:id="@+id/btn_share_friend_circle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="分享到朋友圈"/>

    <Button
        android:id="@+id/btn_share_friend"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="分享給好友"/>

    <Button
        android:id="@+id/btn_pay"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="微信支付"/>
</LinearLayout>

佈局文件很簡單,就LinearLayout裡面放了幾個TextView,跟幾個按鈕。

WeiXin.java 用於EventBus來傳送消息,微信sdk有個很奇怪的地方,就是不管登錄、分享、支付之後都得用一個Activity來接收,所以我們還得從接收的那個activity把結果信息通過EventBus傳遞給MainActivity。雖然用廣播也能實現,但是個人喜歡用EventBus,使用靈活。簡單輕量。

public class WeiXin {
    private int type;//1:登錄 2.分享 3:微信支付
    private int errCode;//微信返回的錯誤碼
    private String code;//登錄成功才會有的code

    public WeiXin() {
    }

    public WeiXin(int type,int errCode, String code) {
        this.type = type;
        this.errCode=errCode;
        this.code = code;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public int getErrCode() {
        return errCode;
    }

    public void setErrCode(int errCode) {
        this.errCode = errCode;
    }
}

Constant.java 常量類,微信appid跟secret的值用兩個常量保存。為了保護隱私這兩個值我已經修改過。

public class Constant {
    public static String WECHAT_APPID="wxda6db2aec81389af";
    public static String WECHAT_SECRET="8fed5a2d510022587ef8a6194c965be3";
}

MainActivity.java 全部代碼貼出來比較亂,暫時貼出MainActivity部分代碼。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private IWXAPI wxAPI;
    private TextView tvNickname,tvAge;
    public static final int IMAGE_SIZE=32768;//微信分享圖片大小限制

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EventBus.getDefault().register(this);//註冊
        wxAPI = WXAPIFactory.createWXAPI(this,Constant.WECHAT_APPID,true);
        wxAPI.registerApp(Constant.WECHAT_APPID);

        findViewById(R.id.btn_login).setOnClickListener(this);
        findViewById(R.id.btn_share_friend_circle).setOnClickListener(this);
        findViewById(R.id.btn_share_friend).setOnClickListener(this);
        findViewById(R.id.btn_pay).setOnClickListener(this);

        tvNickname= (TextView) findViewById(R.id.tv_nickname);
        tvAge=(TextView) findViewById(R.id.tv_age);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_login://微信登錄
                login();
                break;
            case R.id.btn_share_friend_circle://微信分享到朋友圈
                share(true);
                break;
            case R.id.btn_share_friend://微信分享給朋友
                share(false);
                break;
            case R.id.btn_pay://微信支付
//              先去伺服器獲取支付信息,返回一個WeiXinPay對象,然後調用pay方法
                showToast("微信支付需要伺服器支持");
                break;
        }
    }

    /**
     * 這裡用到的了EventBus框架
     * @param weiXin
     */
    @Subscribe
    public void onEventMainThread(WeiXin weiXin){
        Log.i("ansen","收到eventbus請求 type:"+weiXin.getType());
        if(weiXin.getType()==1){//登錄
            getAccessToken(weiXin.getCode());
        }else if(weiXin.getType()==2){//分享
            switch (weiXin.getErrCode()){
                case BaseResp.ErrCode.ERR_OK:
                    Log.i("ansen", "微信分享成功.....");
                    break;
                case BaseResp.ErrCode.ERR_USER_CANCEL://分享取消
                    Log.i("ansen", "微信分享取消.....");
                    break;
                case BaseResp.ErrCode.ERR_AUTH_DENIED://分享被拒絕
                    Log.i("ansen", "微信分享被拒絕.....");
                    break;
            }
        }else if(weiXin.getType()==3){//微信支付
            if(weiXin.getErrCode()==BaseResp.ErrCode.ERR_OK){//成功
                Log.i("ansen", "微信支付成功.....");
            }
        }
    }
    
    ..........

    public void showToast(String message){
        Toast.makeText(this,message,Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);//取消註冊
    }
}
  • onCreate 註冊EventBus,通過WXAPIFactory創建IWXAPI類,並且註冊appid,給四個按鈕按鈕設置點擊事件。查找顯示名字跟年齡的兩個TextView。
  • onClick 點擊事件監聽,根據id來判斷點擊不同的按鈕,跳轉到相應的方法,這些方法沒貼出來來,等會單獨講。
  • onEventMainThread(WeiXin weiXin) 用來接收消息,這個方法有個參數,用來判斷類型,就是我們用EventBus發送時參數必須是WeiXin類型。首先判斷type,是登錄還是分享還是支付。登錄成功情況下會獲取到code,根據code然後我們就能獲取到微信用戶信息。
  • showToast Toast提示
  • onDestroy 取消EventBus註冊

微信登錄

微信登錄流程有以下三個步驟:

  • 微信授權登陸
  • 根據授權登陸code 獲取該用戶token
  • 根據token獲取用戶資料

當我們點擊登錄按鈕的時候,調用的是login方法。這個方法就在MainActivity裡面。就是給微信發起一個登錄請求,彈出一個授權界面。

public void login(){
    SendAuth.Req req = new SendAuth.Req();
    req.scope = "snsapi_userinfo";
    req.state = String.valueOf(System.currentTimeMillis());
    wxAPI.sendReq(req);
}

在你的包名相應目錄下新建一個wxapi目錄,然後在wxapi目錄下新增一個WXEntryActivity類,用來接收登錄授權以及分享時微信的回調信息。這個類繼承自Activity,需要實現IWXAPIEventHandler介面。

package com.ansen.shoenet.wxapi;
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    private IWXAPI wxAPI;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        wxAPI = WXAPIFactory.createWXAPI(this,Constant.WECHAT_APPID,true);
        wxAPI.registerApp(Constant.WECHAT_APPID);
        wxAPI.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent){
        super.onNewIntent(intent);
        wxAPI.handleIntent(getIntent(),this);
        Log.i("ansen","WXEntryActivity onNewIntent");
    }

    @Override
    public void onReq(BaseReq arg0) {
        Log.i("ansen","WXEntryActivity onReq:"+arg0);
    }

    @Override
    public void onResp(BaseResp resp){
        if(resp.getType()== ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX){//分享
            Log.i("ansen","微信分享操作.....");
            WeiXin weiXin=new WeiXin(2,resp.errCode,"");
            EventBus.getDefault().post(weiXin);
        }else if(resp.getType()==ConstantsAPI.COMMAND_SENDAUTH){//登陸
            Log.i("ansen", "微信登錄操作.....");
            SendAuth.Resp authResp = (SendAuth.Resp) resp;
            WeiXin weiXin=new WeiXin(1,resp.errCode,authResp.code);
            EventBus.getDefault().post(weiXin);
        }
        finish();
    }
}

onCreate、onNewIntent、onReq這三個方法是固定寫法。onResp方法接收微信結果信息,首先判斷類型,根據不同的類型去封裝WeiXin對象,如果是登錄操作,把code傳入進去,然後把封裝好的WeiXin對象通過EventBus發送出去。MainActivity的onEventMainThread方法就會接收到這個消息。最後調用finish關閉當前的activity。

WXEntryActivity記得在AndroidManifest.xml中註冊

<activity
    android:exported="true"
    android:name=".wxapi.WXEntryActivity"/>

繼續回到首頁的onEventMainThread,如果登錄類型調用getAccessToken(),並且傳入code。根據code獲取access_token,這個url是微信公開的,需要傳入三個參數,appid、secret、code。請求成功之後會返回access_token跟openid等信息。

public void getAccessToken(String code){
    String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
            "appid="+Constant.WECHAT_APPID+"&secret="+Constant.WECHAT_SECRET+
            "&code="+code+"&grant_type=authorization_code";
    HTTPCaller.getInstance().get(WeiXinToken.class, url, null, new RequestDataCallback<WeiXinToken>() {
        @Override
        public void dataCallback(WeiXinToken obj) {
            if(obj.getErrcode()==0){//請求成功
                getWeiXinUserInfo(obj);
            }else{//請求失敗
                showToast(obj.getErrmsg());
            }
        }
    });
}

獲取到access_token跟openid之後繼續調用getWeiXinUserInfo方法獲取用戶信息。這樣就能取到當前微信app登錄的用戶一些信息。有昵稱、年齡、頭像地址、語言等基本信息。在企業開發中,到了這一步就可以拿著這些信息調用自己伺服器的登錄介面。當然我們這邊就把昵稱跟年齡給TextView顯示下。

public void getWeiXinUserInfo(WeiXinToken weiXinToken){
    String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+
            weiXinToken.getAccess_token()+"&openid="+weiXinToken.getOpenid();
    HTTPCaller.getInstance().get(WeiXinInfo.class, url, null, new RequestDataCallback<WeiXinInfo>() {
        @Override
        public void dataCallback(WeiXinInfo obj) {
            tvNickname.setText("昵稱:"+obj.getNickname());
            tvAge.setText("年齡:"+obj.getAge());
            Log.i("ansen","頭像地址:"+obj.getHeadimgurl());
        }
    });
}

WeiXinToken跟WeiXinInfo這兩個實體類就不貼代碼了,WeiXinToken用來映射獲取訪問token介面返回的json。WeiXinInfo用來映射獲取用戶介面返回的json。

微信分享

分享有兩種分享到朋友圈跟分享給好友,統一調用share方法。傳入一個boolean類型來判斷是否分享到朋友圈。

public void share(boolean friendsCircle){
    WXWebpageObject webpage = new WXWebpageObject();
    webpage.webpageUrl = "www.baidu.com";//分享url
    WXMediaMessage msg = new WXMediaMessage(webpage);
    msg.title = "分享標題";
    msg.description = "分享描述";
    msg.thumbData =getThumbData();//封面圖片byte數組

    SendMessageToWX.Req req = new SendMessageToWX.Req();
    req.transaction = String.valueOf(System.currentTimeMillis());
    req.message = msg;
    req.scene = friendsCircle ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
    wxAPI.sendReq(req);
}

分享內容有很多格式,分享圖片、分享視頻、分享消息。我們這邊就分享消息為例,也是分享比較常見的格式。首先new一個WXWebpageObject對象,設置標題、內容、打開鏈接、封面等。最後調用wxAPI的sendReq放鬆一個請求。

分享跟登錄一樣,都會回調WXEntryActivity,然後又把分享結果發送給MainActivity.onEventMainThread方法。

支付
支付首先需要請求我們自己的伺服器,獲取支付信息。獲取成功之後調用pay方法。

public void pay(WeiXinPay weiXinPay){
    PayReq req = new PayReq();
    req.appId = Constant.WECHAT_APPID;//appid
    req.nonceStr=weiXinPay.getNoncestr();//隨機字元串,不長於32位。推薦隨機數生成演算法
    req.packageValue=weiXinPay.getPackage_value();//暫填寫固定值Sign=WXPay
    req.sign=weiXinPay.getSign();//簽名
    req.partnerId=weiXinPay.getPartnerid();//微信支付分配的商戶號
    req.prepayId=weiXinPay.getPrepayid();//微信返回的支付交易會話ID
    req.timeStamp=weiXinPay.getTimestamp();//時間戳

    wxAPI.registerApp(Constant.WECHAT_APPID);
    wxAPI.sendReq(req);
}

weiXinPay的值應該是我們從自己伺服器獲取的,然後把返回信息封裝到PayReq對象中,最後調用wxAPI的sendReq方法發起請求。

在wxapi目錄下新增一個WXPayEntryActivity類,這個類跟WXEntryActivity同級,用來接收微信支付的回調信息。這個類繼承自Activity,需要實現IWXAPIEventHandler介面。

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    private IWXAPI wxAPI;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        wxAPI = WXAPIFactory.createWXAPI(this, Constant.WECHAT_APPID);
        wxAPI.handleIntent(getIntent(), this);
    }
    
    @Override
    protected void onNewIntent(Intent intent){
        super.onNewIntent(intent);
        setIntent(intent);
        wxAPI.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq baseReq) {}

    @Override
    public void onResp(BaseResp resp) {
        Log.i("ansen", "微信支付回調 返回錯誤碼:"+resp.errCode+" 錯誤名稱:"+resp.errStr);
        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX){//微信支付
            WeiXin weiXin=new WeiXin(3,resp.errCode,"");
            EventBus.getDefault().post(weiXin);
        }
        finish();
    }
}

其他方法都是固定寫法,在onResp中判斷如果是微信登錄,就封裝一個WeiXin對象,然後發送EventBus請求。這樣MainActivity的onEventMainThread就會接收到這個WeiXin對象。

WXPayEntryActivity記得在AndroidManifest.xml中註冊。

<activity
    android:exported="true"
    android:name=".wxapi.WXPayEntryActivity"/>

項目結構圖如下所示,從圖中我們看到軟體包名是com.ansen.shoenet。接收微信登錄支付返回的Activity的包名必須是com.ansen.shoenet.wxapi。兩個activity的名字也是固定寫法。

project_structure

簽名

微信登錄分享支付都有一個簽名驗證,這個很麻煩,導致每次調試都需要重新簽名。

首先用android studio生成一個正式的簽名文件,簽名文件是.jks結尾的,這個簽名文件是你以後打線上包一直要用到的。然後用這個簽名文件生成apk。這個時候我們的app就有了正式簽名。把正式簽名的apk發送到手機上進行安裝。

並且下載一個簽名生成工具安裝,這個工具用於獲取安裝到手機的第三方應用簽名的apk包。微信官方下載地址:

https://res.wx.qq.com/open/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android2.apk

以上兩個app都安裝好了之後打開從微信下載的那個app,軟體名字叫「GenSignature」,有一個輸入框,輸入我們軟體的包名,點擊Get Signature按鈕.效果圖如下:
get_signature

把那行綠色的16進位數炒下來保存到txt文本中。

微信sdk官網後臺配置

官網地址:

https://open.weixin.qq.com/

在微信sdk首頁,有個管理中心點擊之後預設就是移動應用,如果還沒有創建移動應用就先創建一個,如果有了就點擊當前的應用後面的查看按鈕,就會進入應用詳細界面。

在應用詳細界面一直往下滾動,滾到最底部有個開發信息。點擊修改,進入修改界面,在修改界面滾動到最下麵,效果圖如下所示:
app_info
首先我們在Android應用這裡打上勾,然後填寫應用簽名,這個簽名都是我之前要你們保存到記事本上的那個值,包名就是app包名。點擊保存。

運行軟體

登錄之後效果圖如下:

login_success

分享到朋友圈如下:

share_friend_circle

分享給朋友:

share_friend

微信支付沒法測試,因為需要伺服器支持。

微信官方開發文檔

我這偏文章只是針對現在微信的sdk版本接入,但是sdk是有可能變化的,版本變化、介面變化等。所以建議大家還是以官方文檔為主。我的文章提供參考。

移動應用微信登錄開髮指南

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=219192a54f13e8e7011ced8e4ce5b36b699629c4&lang=zh_CN

Android微信支付開發手冊

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317784&token=219192a54f13e8e7011ced8e4ce5b36b699629c4&lang=zh_CN

註意事項

接入微信sdk有很多需要註意的地方,這裡我們最後再來做一個總結。

  • 微信登陸,分享,支付回調的Activity包名跟類名一定要嚴格按照要求去寫
  • 接收回調的是Activity一定要在AndroidManifest.xml中中註冊
  • Constant裡面兩個常量的值要去微信申請並且創建應用才有的,這裡需要改成你們申請的值。
  • 需要訪問網路所以記得在AndroidManifest.xml中添加許可權
  • 調用微信的登陸,分享,支付你的安裝包一定要有簽名,簽名信息一定要跟你在微信官網上配置的簽名信息一致
  • 微信沒有客服支持.....如果出了問題看官方的Demo或者官方API
  • 微信SDK經常升級,如果你開發的時候有最新的就用最新的吧.....

最後的最後

你們直接運行我的demo是不行的,因為你們沒有的jks文件,沒法簽名,並且源碼中的appid跟secret被我修改過了,是不能使用的,但是你們可能又想看運行效果,所以我在項目下建了個apk文件夾,裡面放了一個可以測試微信登錄分享的apk安裝包。

源碼下載

如果你想第一時間看我的後期文章,掃碼關註公眾號,每周不定期推送Android開發實戰教程文章...

      Android開發666 - 安卓開發技術分享
             掃描二維碼加關註

Android開發666


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、函數的調用方式 1.作為函數,一種直接易懂的方式(即函數調用模式)。 2.作為方法,方法是連接在對象上的,被這個對象調用,這種形式就是面向對象編程。 3.作為構造器,在構造的過程中一個新的對象被創建出來。 4.經由函數的apply或者call方法。 二、函數參數 1.傳入參數 (1)傳入變數多於 ...
  • 1. 創建對象的幾種方式 ...
  • JSONP:一種非官方跨域數據交互協議 JSONP怎麼產生的 JSONP的原理 看上面的來源加以理解 上面說過了,script是不受跨域影響的 那麼我們可以在我們代碼中引用B伺服器的文件 在B伺服器端demoResult.aspx會根據我們傳的callback參數jsonpCallback自動返回數 ...
  • - 是express框架下的一個方法,可以根據請求路徑名查找某個文件下文件名字和路徑名相同的文件 - 3.X裡面有20多個中間件,但是在4.X裡面 只保留了express.static - 語法 express.static('/設置一下請求路徑/路徑名','要被查找文件夾的絕對路徑') 請求路徑後 ...
  • 前端面試經常會問關於原型鏈的知識,今天我總結了一下關於原型鏈的內容,希望對廣大小白一點點參考~ 什麼是原型? 在 js 中,對象都有 __proto__ 屬性, 就是指這個對象的原型,如果構造函數 A 實例化一個對象 B,那麼 A.prototype 就是 B 的原型。也就是: 什麼是原型鏈? 介紹 ...
  • 效果圖: ...
  • - 安裝 body-parser模塊- npm install body-parser -S- 調用- let bodyParser=require('body-parser');- 設置中間件- app.use(bodyParser.urlencoded({extended:true}));- 判 ...
  • 轉載請註明原創出處,謝謝! 問題 這個Xmn設置為1G,,我用jmap heap 看,這個Eden From To怎麼不是一個整8:1:1的關係呢? 我看記憶體分配還是沒變,我Xmn1g,感覺From、To應該都是102.4M才對,現在是102.375M。 執行命令 結果: 發現很奇怪,的確和我們相信 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...