SignalR ——Android实践

SignalR 的版本:aspnetcore-2.2, Java SignalR-1.0.0

一、先说几个点

1、我使用SignalR的时候服务器使用的是自签名的HTTPS证书,所以OkHttp是无法直接解析的,会报错。需要修改SignalR里面OkHttp部分的源码,让其信任所有的HTTPS连接。当然,我这个项目是在内部网络里面使用的,所以才直接对信任了所有的HTTPS连接。

2、还有SignalR的版本问题,服务端的版本和客户端的版本一定要匹配。我刚开始做的时候服务端是不知道用的哪个版本的,也没给我说清楚。我是直接按照微软官网的SignalR的文档来写的,但是与后台对接的时候却连不上,最后后台是换成了我的那个客户端对应的SignalR的服务器版本才连接成功的。

3、SignalR的引入
如果不需要对HTTPS进行全部信任的话可以直接引入微软官方的SignalR的Java版SDK

//gradle
implementation 'com.microsoft.signalr:signalr:1.0.0'

如果需要的话就可以下载我修改过的SignalR,主要就是对里面的OkHttp加个一个Https的全部信任。
https://github.com/lfork/androiddemo/signalr

二、相关代码(Kotlin)

建立连接

关键类com.microsoft.signalr.HubConnection和com.microsoft.signalr.HubConnectionBuilder

  val hubConnection = HubConnectionBuilder.create(serverUrl).build()hubConnection.start().blockingAwait()

注意需要调用blockingAwait()来等待连接成功,我之前写的时候没有加,然后在调用 hubConnection.start()后直接就调用了向服务器发送消息的方法,这样子会发送失败。因为你连接都没建立好,所以要先等下。

关闭连接

 hubConnection.stop()

对被动关闭进行监听(比如网络异常)

hubConnection.onClosed {
}

客户端调用服务端方法

 /*** Invokes a hub method on the server using the specified method name.* Does not wait for a response from the receiver.** @param method The name of the server method to invoke.* @param args   The arguments to be passed to the method.*/public void send(String method, Object... args)

从SignalR源码可以看到,我们只需要把服务端注册好的方法名和参数传递进行即可

eg

  hubConnection.send("SendMessageAsync", "" + "连接测试", "test")

服务端调用客户端方法

客户端需要在hubConnection对象执行start()方法之前对服务端需要调用的方法进行注册。然后就可以接收服务端的消息了。

①删除用户

//定义处理用户删除的action(方法体)val deleteAction = { id: String ->Log.d("SignalRSyncTask", "删除用户 $id")//doSomthing()Unit}//对action进行注册
//第一个参数是对方法名的注册,第二个参数相当于方法体,第三个参数就是客户端注册方法的参数了,
//我们可以看到deleteAction的lambda里面写了一个id:String。
hubConnection.on("DeleteUser", deleteAction, String::class.java)

②添加或者更新用户

//定义处理相关的action(方法体)
val addOrUpdateAction = { userInfoModel: User ->Log.d("SignalRSyncTask", "添加或者更新用户 ${userInfoModel.id}")userInfoChangedListenerList.forEach {it.userAddedOrUpdated(userInfoModel)}Unit
}//对action进行注册
hubConnection?.on("AddOrUpdateUser", addOrUpdateAction, User::class.java)

完整代码参考

代码里面还维护了一个监听,开启signalR的时候可以进行监听的注册,如果服务端有调用客户端方法的话就会进行提醒

import android.util.Log
import com.lfork.frtest.FRApplication
import com.lfork.frtest.data.userinfo.User
import com.lfork.frtest.syncservice.tasklistener.UserInfoChangedListener
import com.microsoft.signalr.HubConnection
import com.microsoft.signalr.HubConnectionBuilder
import java.lang.Exception/*** Created by L.Fork** @author lfork@vip.qq.com* @date 2019/01/28 18:01*/
class SignalRSyncTask {private var hubConnection: HubConnection? = nullprivate var userInfoChangedListenerList = ArrayList<UserInfoChangedListener>()fun start(serverUrl:String) {FRApplication.mThreadPool?.execute {hubConnection = HubConnectionBuilder.create(serverUrl).build()hubConnection?.onClosed {close() }val connectionTestAction = { name: String, message: String ->Log.d("SignalRSyncTask", "SignalR 连接成功 $name - $message")Unit}val addOrUpdateAction = { userInfoModel: User ->Log.d("SignalRSyncTask", "添加或者更新用户 ${userInfoModel.id}")userInfoChangedListenerList.forEach {it.userAddedOrUpdated(userInfoModel)}Unit}val deleteAction = { id: String ->Log.d("SignalRSyncTask", "删除用户 $id")userInfoChangedListenerList.forEach {it.userDeleted(id.toInt())}Unit}hubConnection?.on("ReciveMessage",connectionTestAction,String::class.java,String::class.java)hubConnection?.on("AddOrUpdateUser", addOrUpdateAction, User::class.java)hubConnection?.on("DeleteUser", deleteAction, String::class.java)try {//This is test blocking callhubConnection?.start()?.blockingAwait()hubConnection?.send("SendMessageAsync", "" + "连接测试", "test")} catch (e:Exception){e.printStackTrace()}}}fun addUserInfoChangedListener(userInfoChangedListener: UserInfoChangedListener) {userInfoChangedListenerList.add(userInfoChangedListener)}fun close() {userInfoChangedListenerList.clear()hubConnection?.stop()}}

三、参考文档

Microsoft官方参考文档

 

作者:lfork

原文地址: https://www.jianshu.com/p/43c79a7d0e3a

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ArcGIS遇上Python】ArcGIS批量处理栅格影像(NDVI)归一化完整案例代码

文章《ArcGIS栅格影像(NDVI)归一化处理的两种方法精解》详细介绍了ArcGIS中进行NDVI影像归一化处理的两种方法,但是无法批量进行,本文就放大招用Python实现批量NDVI归一化处理,大大提高了工作效率,还不赶快Get了? 完整Python代码: import arcpy from arcpy import env…

Spark1.0.0 属性配置

1&#xff1a;Spark1.0.0属性配置方式Spark属性提供了大部分应用程序的控制项&#xff0c;而且能够单独为每一个应用程序进行配置。在Spark1.0.0提供了3种方式的属性配置&#xff1a;SparkConf方式 SparkConf方式能够直接将属性值传递到SparkContext&#xff1b;SparkConf能够对…

Lync Server 2010迁移至Lync Server 2013部署系列 Part1: 扩展AD架构

由于最近直在忙Lync 升级&#xff0c;好久没有更新博客了&#xff0c;今天开始将对最近做的Lync Server 2010迁移至Lync Server 2013项目做一个系列的部署操作更新&#xff0c;希望能给即将在企业中部署的兄弟们有所帮助&#xff0c;在这个测试环境中&#xff0c;企业 前端池共…

Android之BaseRecyclerViewAdpater(3.0.4版本)当页面第二次滑到底部的时候没有触发OnLoadMoreListener监听的onLoadMore函数

1 、问题 BaseRecyclerViewAdpater(3.0.4版本)当页面第二次滑到底部的时候没有触发OnLoadMoreListener监听的onLoadMore函数,也就是梅如下监听的地方 adapter?.loadMoreModule?.setOnLoadMoreListener(object : OnLoadMoreListener {override fun onLoadMore() {Log.d(TAG,…

Hello Playwright:(7)模拟键盘和鼠标

尽管在上一节中&#xff0c;我们已经能够通过FillAsync或ClickAsync来实现输入和点击元素。但是&#xff0c;还有其他场景&#xff0c;我们必须模拟用户使用键盘、鼠标与页面交互。例如在线文档&#xff1a;Page.Keyboard 对象Keyboard提供用于管理虚拟键盘的 API&#xff0c;它…

精通Hibernate:通过Hibernate操纵对象

http://developer.51cto.com/art/201202/315954.htm转载于:https://www.cnblogs.com/iOS-mt/p/5973683.html

【ArcGIS遇上Python】Python批量将多个文件夹下的多个影像数据镶嵌至新栅格

ArcGIS虽然可以实现一次多个影像同时参与,拼接成一个整的影像,但是通常情况下,多个影像并不在同一个文件夹下,这样拼接的时候需要逐个手动进行添加,如果数据量大的话,跟不就不可取,针对这一问题,本文采用Python,实现将多个文件夹下的多个影像拼接,高效快速。 我们以…

2019全球开发者调查:仅2%的人996,Python并不是最受喜爱的语言

导读&#xff1a;开发者社区正在发生哪些变化&#xff1f;Stack Overflow 的最新调查获得了一些预料之外的结果&#xff1a;Java 语言开发者的平均收入不到 35 万元人民币&#xff0c;成为了收入最低的群体&#xff1b;另一方面&#xff0c;人工智能领域流行的 Python 并不是最…

Java 编写程序 创建一个游戏【5、6两章的内容】【第5章】

每次使用单边大脑的时间不要太久&#xff0c; 连续使用左边脑30 分钟如同使用左臂 30 分钟一样&#xff0c; 周期性性地交换让大脑两侧轮流休息。 左脑活动包括了循序渐进的工作&#xff0c;解决逻辑问题与分析&#xff1b; 右脑的活动包括了阴雨、创造性思考、模式匹配与可视化…

一般地

2019独角兽企业重金招聘Python工程师标准>>> 1.EO的Updatable属性默认为Always&#xff0c;基于EO创建的VO也是。而基于SQL创建VO的Updatable属性默认为Never&#xff0c;如果要修改&#xff08;例如将VO拖至页面生成Form用于新增&#xff09;&#xff0c;则需将该属…

【CASS精品教程】南方CASS内业基本作图--野外测记草图法绘制常见地物教程

文章目录 一、系统环境:1.1 操作系统1.2 应用环境二、实例数据:2.1 野外测点CASS坐标格式数据2.2 野外测记草图三、地物绘制前准备操作3.1 定显示区3.2 展野外测点点号:3.3 绘图测点定位模式的选择四、野外测记草图绘制常见基本地物4.1绘制交通设施4.2绘制居民地4.3 绘制地貌…

最新!2019 年中国程序员薪资生存调查报告出炉

此调查&#xff0c;是对北京、上海、广东和浙江等全国 29 个省、直辖市及特别行政区的 26W 优秀程序员进行了一次详细的调查&#xff0c;形成本报告。 根据中国互联网络信息中心&#xff08;CNNIC&#xff09;近日发布第 43 次《中国互联网络发展状况统计报告》。截至 2018 年 …

快速掌握 ASP.NET 身份认证框架 Identity - 登录与登出

推荐关注「码侠江湖」加星标&#xff0c;时刻不忘江湖事这是 ASP.NET Core Identity 系列的第三篇文章&#xff0c;上一篇文章讲解了如何在 ASP.NET Core Identity 中实现用户注册。那么&#xff0c;这篇文章讲一讲如何在 ASP.NET Core Identity 中实现用户的登录与登出。点击上…

C语言试题七十九之请编写函数实现自然底数 e=2.718281828

📃个人主页:个人主页 🔥系列专栏:C语言试题200例目录 💬推荐一款刷算法、笔试、面经、拿大公司offer神器 👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 请编写函数…

PHP和Mysql处理IP地址

PHP: 32位整型&#xff08;bigint&#xff09; ip2long (IP —> long) long2ip (long —> ip) Mysql: 10位无符号整型(INT UNSIGNED) INET_ATON (IP —> long) INET_NTOA (long —> ip) 转载于:https://www.cnblogs.com/yudis/articles/5976362.html

如何创建NFT并OpenSea上展示《alchemy How to Develop an NFT Smart Contract》译

翻译&#xff1a;1_bit 原文&#xff1a;https://docs.alchemy.com/docs/how-to-develop-an-nft-smart-contract-erc721-with-alchemy 注&#xff1a;英文不好各位多多担待 1.如何使用 Alchemy 开发一个 NFT 智能合约 在你第一次使用 solidity 时开发一个智能合约部署在区块…

Jmeter之Bean shell使用(二)

上一篇Jmeter之Bean shell使用(一)简单介绍了下Jmeter中的Bean shell&#xff0c;本文是对上文的一个补充&#xff0c;主要总结下常用的几种场景和方法&#xff0c;相信这些基本可以涵盖大部分的需求。本节内容如下&#xff1a; 一、操作变量 二、操作属性 三、自定义函数 四、…

【ArcGIS风暴】ArcGIS中国地表覆盖数据GlobeLand30预处理(批量投影、拼接、掩膜提取)附成品下载

结果示意图&#xff1a; GlobeLand30是30米空间分辨率全球地表覆盖数据&#xff0c;目前可供下载的有3年的数据&#xff1a;2000-2010-2020。本文主要讲解在ArcGIS10.6平台下进行GlobeLand30的预处理操作&#xff0c;主要预处理步骤包括&#xff1a;批量分幅投影转换、批量分幅…

Asp.Net MVC4入门指南(9):查询详细信息和删除记录

在本教程中&#xff0c;您将查看自动生成的Details和Delete方法。 查询详细信息和删除记录 打开Movie控制器并查看Details方法。 ?Code First 使得您可以轻松的使用Find方法来搜索数据。一个重要的安全功能内置到了方法中。方法首先验证Find方法已经找到了一部电影&#xff0c…

漫画:什么是架构师?

于是&#xff0c;小灰去向大黄请教 这是有关未来的故事&#xff1a; 从前&#xff0c;有一个赶路的人路过一片工地&#xff0c;看到三个年轻人在工地上搬砖。 于是&#xff0c;他问其中一个人&#xff1a; 于是&#xff0c;他又问了第二个人&#xff1a; 于是&#xff0c;他又问…