精华内容
下载资源
问答
  • WEB即时通讯框架

    2017-06-26 16:28:49
    一个纯JS的即时通讯框架,自动兼容IE8+ 亲测可用
  • C#Web即时通讯Comet框架

    2017-10-30 17:08:29
    使用Comet技术实现HTML长连接,对Comet框架进行了一定的封装,允许对发送的结果进行自定义扩展,并实现Web即时通讯的例子
  • HTML5和java模仿QQ 实现即时通讯
  • t-io: 百万级TCP长连接即时通讯框架

    万次阅读 2017-05-28 10:15:38
    t-io: 百万级TCP长连接即时通讯框架,让天下没有难开发的即时通讯 t-io: 百万级TCP长连接即时通讯框架,让天下没有难开发的即时通讯 t-io是基于jdk aio实现的易学易用、稳定、性能强悍、将多线程运用到极致、内置...


    t-io: 百万级TCP长连接即时通讯框架,让天下没有难开发的即时通讯


    • t-io是基于jdk aio实现的易学易用、稳定、性能强悍、将多线程运用到极致、内置功能丰富、核心代码只有3000多行(2017年05月13号统计)的即时通讯框架(广义上的即时通讯,并非指im),字母 t 寓意talent。
    • 同类型的框架还有voovannettyminabaseio等,不喜欢t-io的可以去尝试了解这几个,t-io对所有人按LGPL协议开源,但只服务于品行良好的开发人员!

    常见应用场景

    • IM(官方提供了im例子,含web端)
    • 实时监控
    • 推送服务(已内置API)
    • RPC
    • 游戏
    • 物联网(已有很多案例)
    • 其它实时通讯类型的场景,不一一列举

    晒一下作者花两天时间用t-io和layim做的web im(服务器由某公司免费提供,只有2M带宽,最近被Ddos攻击,所以随时都可能暂停而导致你访问失败)

    • 先感谢一下贤心提供这么好的ui作品,也欢迎大家去捐赠获取layim,本人捐赠了layim只是贤心又零差价地回捐了t-io
    • 东西刚刚出来,还需要打磨,有问题在所难免,毕竟只花了两天时间。
    • 演示地址(2M带宽,请勿压测,谢谢!)
    • 截图

    image


    image


    重点强调

    maven坐标

    <dependency>
        <groupId>org.t-io</groupId>
        <artifactId>tio-core</artifactId>
        <version>1.7.0.v20170501-RELEASE</version>
    </dependency>
    

    t-io特点

    极简洁、清晰、易懂的API

    • 没有生涩难懂的新概念,原生态bytebuffer既减少学习成本,又减少各种中间对象的创建
    • 只需花上30分钟学习helloworld,就能较好地掌握并实现一个性能极好的即时通讯应用

    极震撼的性能

    • 单机轻松支持百万级tcp长连接,彻底甩开业界C1000K烦恼(不过现在已经有不少公司已经搞定c1000K问题了);
    • 最高时,每秒可以收发500万条业务消息,约165M(1.6.9版本数据,想验证的,后面有验证步骤

    对开发人员极体贴的内置功能

    • 内置心跳检测
    • 内置心跳发送
    • 各种便捷的绑定API
    • 各种便捷的发送API
    • 一行代码拥有自动重连功能
    • 各项消息统计等功能,全部一键内置搞定,省却各种烦恼

    一张思维导图胜过千言万语(部分方法在未发布的1.7.1版本中)


    image


    各种传送门

    性能数据

    • 需要验证的,请按后面提供的验证步骤来,对于t-io的数据,要么相信作者所说,要么自己亲手去测,网上的抹黑造谣谩骂很多,但真理来自测试。验证完毕后,自己偷着乐就好,注意规避网上那些喷子,不要回复他们(t-io被黑了几个月,这两天,作者本人抓住确凿证据后正面回应了两个人,结果引来了更多的喷子(简单点看了几个 人,基本是些活跃度和访问量极低的用户),前车之鉴)。如果你对测试数据还有疑问,可以debug进去看看各个步骤,重点是多沟通,防止误判
    • IM实例收发速度500万条/秒----此数据系网友提供(i7 6700 + 固态硬盘 + win10),作者本地只跑到了333万/秒
    • IM实例17.82万TCP长连接且正常收发消息只消耗800M内存,CPU使用率极低,目测t-io可以支撑200万长连接
    • 17.82万长连接 + 各种破坏性测试,服务器内存保持稳定(600多M到900M间)

    性能测试步骤

    测试单机吞吐量(实际上就是非网络环境啦)

    1. 机器准备
      • CPU: i7 6700 / i7 4790
      • 内存:8G/4G
      • 操作系统:windows7/windows10
      • 说明:客户机和服务器位于同一台机器
    2. 测试步骤
      • 参数调优:修改t-io\dist\examples\im\client\startup.bat,把-Dtio.default.read.buffer.size=512的值换成4096
      • 参数调优:修改t-io\dist\examples\im\server\startup.bat,把-Dtio.default.read.buffer.size=512的值换成4096
      • 双击 "bin/start-im-server.bat" 启动im server
      • 双击 "bin/start-im-client.bat" 启动im client
      • 保持下图参数进行测试(强调:你需要多试几次,前面几次的性能数据是最差的,貌似跟线程池的预热有关系,有研究的朋友可以交流一下image
    3. 测试结果
      • 500万条/秒约165M----此数据系网友提供(i7 6700 + 固态硬盘 + win10)
      • 333万条/秒约97M----此数据系本人亲测数据(i7 4790 + 固态硬盘 + win7),测试参数与上图略有差别,不一一说明
    4. 测试说明
      • 数据中的消息条数指的是业务包,不是指tcp的交互次数,了解tcp协议的人知道,tcp是双向确认可靠的传输协议,对业务而言,其实并不关心tcp了多少次,而是我们的业务数据收发了多少条。
      • 请用t-io 1.6.9分支进行测试,1.7.0加了链路行为跟踪功能、1.7.1会加上ip防黑功能,这些功能会使t-io框架本身的性能降低(就像操作系统一个开了防火墙,一个没开防火墙,性能不是一个级别的)。作为一个io框架,其实并不需要实现这些功能,但是为了让业务层更舒服,t-io还是舍弃了亮眼的性能数据去拥抱更实用的业务层功能。
      • netty是一个知名度极高的一个框架,而且功能更多,t-io如果满足不了你或不是你的菜,可以尝试netty

    测试centos下可以支持多少长连接数

    1. 机器准备
      • 服务器一台:centos6.x, 虚拟机,一个4核E5 CPU,内存16G
      • 客户机11台:windows,硬件没什么特别要求,能跑起1.62万个长连接,配置不低得离谱就行
    2. 测试步骤

      • 修改centos操作系统参数,使之支持更大的长连接数,细节略(可百度之)
      • 在centos上运行 "bin/start-im-server.sh" 启动im server
      • 修改dist\examples\im\client\config\app.conf,参考下面的值,注意把server指向centos的ip

        #服务器
        server=127.0.0.1
        
        #服务器port
        port=9321
        
        #连接多少个连接到服务器
        client.count=16200
        
        #进入到哪个组
        group=g
        
        #聊天消息发的内容
        chat.content=he
        
        #一次发多少条(这个数字不要太大)
        send.count=1
        
      • 把dist\examples\im\client拷到各客户机并运行"bin/start-im-client.bat"

    3. 测试结果

      • 11个客户机 ,每个客户机连16200个TCP连接,服务器一共承受17.82万TCP长连接,服务器内存只消耗800M,CPU使用率极低(其中有一台客户担任破坏性测试机)
      • 根据测试结果初步推测:乐观点:t-io支持200万长连接没什么问题,保守点:100万吧,各位有条件的可以测测,毕竟推测的数据有时候会让人跌眼境。
    4. 测试说明

      • 因为这17.82万长连接位于同一个组中,你用客户机发一条消息,服务器就要推送17.82万条数据,所以在发消息时,请慎重,当然如果你非要把内存、CPU耗光,然后看t-io宕机才高兴,只能说t-io不是你的菜,你还是另请高明吧。
      • 这些数据是1.6.9版本测出来的,1.7.0加了链路行为跟踪功能、1.7.1会加上ip防黑功能,这些功能的增加对tcp长连接个数没什么影响,但是可能内存会增加一些,毕竟多了不少维护数据。
      • 不管怎么说,用在生产环境,不管用什么框架,都是要自己测一遍的,有问题可以随时找作者,不接受恶意找茬,同时作为开源免费软件,作者也有权拒绝一切服务,这点请知悉----开源,只是把代码本身按照某种协议贡献出来,并无义务给你服务,你用得不爽,请另请高明。
      • netty是一个知名度极高的一个框架,而且功能更多,t-io如果满足不了你或不是你的菜,可以尝试netty

    t-io学习步骤(供参考,具体步骤根据各人而异)

    学习t-io的最好方式,是从helloworld的例子入手,顺瓜摸藤阅读t-io的源代码,已经有很多人阅读过t-io的源代码,譬如j-net的作者、hutool的作者、天蓬小猪守护天使,并且反馈良好,源代码毕竟只有3000多行,读读无妨!如果懒于阅读代码,就按照下面的步骤来学习吧!

    初步认识t-io

    • 安装1.7以上版本的jdk及maven(已安装的略过此步骤)
    • https://git.oschina.net/tywo45/t-io处下载源代码(已下载的略过此步骤)
    • 双击 "bin/start-im-server.bat" 启动im server
    • 双击 "bin/start-im-client.bat" 启动im client
    • 对着界面把玩几下,测试一把性能数据,对t-io形成感性认识(注意:好的性能数据需要预热几把,让线程池活起来)
    • 熟悉客户端界面(版本不一样,此界面会不一样,以实物为准)image
    • 服务器端界面(版本不一样,此界面会不一样,以实物为准)image

    了解代码目录结构

    所有工程都是maven工程,后续目录有可能稍有变动,不定期更新

    ├─bin----------------脚本目录(方便快速操作)
    │      clean.bat----------------清空所有工程的target目录
    │      clean.sh
    │      deploy.bat----------------作者用来发布到maven中心仓库的脚本,放出来主要是供大家参考
    │      deploy.sh
    │      dist-examples.bat----------------把所有的例子打包到dist目录,方便用户直接执行
    │      dist-examples.sh
    │      install.bat----------------安装工程到本地仓库
    │      install.sh
    │      start-helloworld-client.bat----------------启动helloworld的客户端
    │      start-helloworld-client.sh
    │      start-helloworld-server.bat----------------启动helloworld的服务端
    │      start-helloworld-server.sh
    │      start-im-client.bat----------------启动im的客户端
    │      start-im-client.sh
    │      start-im-server.bat----------------启动im的服务端
    │      start-im-server.sh
    │      start-im-simple-client.bat----------------启动简化版协议的im的客户端
    │      start-im-simple-client.sh
    │      start-im-simple-server.bat----------------启动简化版协议的im的服务端
    │      start-im-simple-server.sh
    │      start-showcase-client.bat----------------启动showcase的客户端
    │      start-showcase-client.sh
    │      start-showcase-server.bat----------------启动showcase的服务端
    │      start-showcase-server.sh
    ├─docs
    │  │  
    │  ├─blog----------------本人博客草稿(大部分博客是在线编辑,所以此处就没有了)
    │  │      
    │  ├─performance----------------一些性能测试截图(随着版本的增多,有些截图已经过时,但仍保留)
    │  │
    │  ├─release----------------新版本发布时的log
    │  
    ├─dist----------------成品
    │  └─examples----------------用t-io写的例子成品
    │      ├─helloworld
    │      │  ├─client----------------helloworld的客户端
    │      │  └─server----------------helloworld的服务端
    │      ├─im
    │      │  ├─client----------------im的客户端
    │      │  └─server----------------im的服务端
    │      │─im-simple
    │      │  ├─client----------------简化版协议的im的客户端
    │      │  └─server----------------简化版协议的im的服务端
    │      └─showcase
    │          ├─client----------------showcase的客户端
    │          └─server----------------showcase的服务端
    └─src
        ├─core----------------t-io的核心代码
        ├─example----------------用t-io写的例子的源代码
        │  ├─parent----------------例子的maven parent
        │  ├─helloworld----------------helloworld的源代码
        │  │  ├─client
        │  │  ├─common
        │  │  └─server
        │  ├─im----------------im的源代码
        │  │  ├─client
        │  │  ├─common
        │  │  └─server
        │  ├─im-simple----------------简化版协议的im的源代码
        │  │  ├─client
        │  │  ├─common
        │  │  └─server
        │  └─showcase----------------showcase的源代码,这个例子是为了帮助用户学习t-io专门写的
        │      ├─client
        │      ├─common
        │      └─server
        └─parent----------------maven工程的parent
    

    导入t-io官方提供的例子

    t-io码云托管地址下载源代码及例子,里面的showcase例子是专门为学习t-io而写的,其设计也是准生产级别的,可以直接拿来做您项目的手脚架。下载完成后,请按下面步骤导入到eclipse中

    image

    image

    image

    学习万能的helloworld例子

    花30分钟看一下t-io官方提供的helloworld,了解一下TCP编程的大概流程,文档传送门: t-io的hello world

    学习用于进阶的showcase例子

    showcase一词是从springside借来的,放这很应景,天蓬元帅就是这样学习的,可以和他交流,他后面会出详细的教程。

    案 例

    案例太多,此处仅列举t-io开源第一个月内的案例,你也可以来t-io开源中国收录地址看看其它网友们反馈的案例

    • 某网管系统(管理数百台刀片服务器的系统)
    • 某直播平台(视频直播+聊天)
    • 某智能设备检测系统(数据采集)
    • 某物联网系统(服务端)
    • 深圳市某在线技术发展有限公司(中银联投资):某网络安全运营支撑平台
    • redisx
    • talent_dubbo
    • 某移动省公司CRM业务受理消息采集平台(数据采集)

    列一下作者本人用过的国产开源软件

    网上很多人对国产开源的印象还停留在n年前,此处列一下作者本人一直在用的部分国产开源软件,其中有的是有争议的,也有暴过漏洞的,但是我们想一下struts、netty、mongodb这些国外知名软件不也暴过严重漏洞吗?

    1. https://www.oschina.net/p/weixin-java-tools-new (使用一年)
    2. http://layim.layui.com(2017年5月11号开始使用)
    3. https://www.oschina.net/p/ztree (使用五年以上吧)
    4. https://www.oschina.net/p/echarts (使用两年以上吧)
    5. http://git.oschina.net/tywo45/talent-validate (使用十年了,开源出来有五年以上吧,原来是博客开源,现在移到开源中国了)
    6. https://www.oschina.net/p/hutool(使用两个月)
    7. https://www.oschina.net/p/t-io(使用五年了,开源出来半年)
    8. https://www.oschina.net/p/druid(使用三年以上吧)
    9. https://www.oschina.net/p/dubbo(使用两年)
    10. https://git.oschina.net/jfinal/jfinal-weixin(使用一年左右)
    11. https://www.oschina.net/p/fastjson(使用三年以上)








    展开全文
  • web即时通讯

    2007-11-25 20:33:41
    前段时间做了个在线聊天,WEB方式的,提供点对面的聊天室和点对点的自由聊天,根据ICEFACES的聊天室修改的,开发基础框架是ICEFACES+JSF。地址:http://help.taxcom.cn...

    前段时间做了个在线聊天,WEB方式的,提供点对面的聊天室和点对点的自由聊天,根据ICEFACES的聊天室修改的,开发基础框架是ICEFACES+JSF。地址:http://help.taxcom.cn

    展开全文
  • 德国联邦国防军未来将使用其自己的加密即时通讯App进行通信。为此军方目前正在测试开源项目Matrix。本文详细解读德国联邦政府未来可能采用的加密即时通讯框架。将来,德国联邦国防军的成员可...

    德国联邦国防军未来将使用其自己的加密即时通讯App进行通信。为此军方目前正在测试开源项目Matrix。本文详细解读德国联邦政府未来可能采用的加密即时通讯框架。

    将来,德国联邦国防军的成员可能会使用基于开源软件Matrix开发的软件,与其相关联的客户端App Riot一起,作为其军用智能手机上的加密即时通讯软件。这是联邦国防部国会国务卿Peter Tauber(CDU)对联邦议院左派网络政治发言人Anke Domscheit-Berg的书面询问作出的回答。

    1BwMessenger

    基于开源软件Matrix开发的即时通讯软件将不仅应用于日常通信。 德国国防部也计划用于数据交换,如“加密且仅用于军用”的数据。 该试点项目叫做BwMessenger。

    Matrix及其关联客户端App Riot的组合,已在法国政府中用作其Whatsapp的替代方案,作为加密通讯软件的基础,法国当局与Matrix社区的开发成员密切合作。 由开发人员Matthew Hodgson领导的Matrix团队显然也参与了德国国防军目前的测试。 毕竟,Twitter上的Matrix团队已经将这个消息高兴地“公开”了。 瑞士则使用即时通讯软件Threema,用于机密数据交换。

    与法国中央政府将所有系统都使用Matrix系统形成鲜明对比的是,目前德国当局的管理存在很大的分歧,即未来应该使用哪个即时通讯系统?例如,在下萨克森州,使用了基于Stashcat的加密即时通讯软件,而德国联邦警察目前正在试点项目中测试开放的XMPP标准。同时,联邦总理府也在尝试开源软件Wire。

    对该问题的回答是:“根据目前的评估,BwMessenger不仅具有在德国联邦国防军中部署的潜力,而且还具有跨部门解决方案的发展潜力”,而且:“德国联邦政府的共同目标是一个安全的,跨部门使用即时通讯服务。” 德国当局将对正在进行的试点项目一一进行评估,然后主管部门最好将最终选择一个统一的解决方案。

    2相关技术

    我们来解读一下,德国国防军这套加密系统里用了哪些技术。

    Matrix

    这个开源通讯框架Matrix可不是你想的那个Matrix, 

    官网:https://matrix.org/  这是一个开源的,安全的去中心化的通讯框架。 由非盈利组织Matrix.org Foundation(注册于英国)负责维护,遵循Apache开源协议,至今已开发五年,2019年6月发布了Beta版本。

    Matrix也是一个通讯标准,提供一个稳定,自洽,自包含和安全的标准,任何人都可以基于其打造自己的即时通讯服务器,客户端,通讯网络等等。简单地说,Matrix专注于后台服务端,为一系列客户端提供API接口。

    上面为其核心功能:即时通讯,端对端加密,VoIP,与其他通讯平台的桥接。项目野心很大,计划打通并桥接现有的诸多即时通讯系统如Telegram, Discord, WhatsApp, Facebook, Hangouts, Signal 等等。社区也非常活跃,目前基于其开发的聊天客户端软件已有多个,有Riot Web,Android,iOS客户端,有用QT开发的Quaternion和Nheko桌面客户端,还有基于Python开发的命令行客户端Weechat(不是Wechat)。

    由开发者贡献的各种服务端,客户端,SDK等开源项目涵盖了绝大多数开发语言。访问 https://matrix.org/docs/projects/try-matrix-now/ 列有几十种开源客户端项目以及SDK:Java、Android、iOS、.NET、Javascript、Python、Golang.......你能想得到的都支持了。

    默认情况下,Matrix使用简单的HTTPS + JSON API作为其基本数据传输,但也包含更复杂的传输,例如WebSocket或通过CoAP + Noise的超低带宽数据传输。coap-proxy是将标准Matrix HTTPS + JSON流量转换为超低带宽CoAP + CBOR + Flate + Noise + UDP网络传输的概念验证项目。 其生成的数据传输使用的带宽比HTTPS + JSON少35-70倍。

    比较有新意的是其去中心化通讯构架。

    Matrix实际上是一个去中心化的对话记录仓储,而不仅仅是消息传递协议。当您在Matrix中发送消息时,该消息将正在参与给定对话的所有用户所在的所有服务器上被复制,这有点类似于在Git代码库之间commit被复制的方式。跨越多个服务器的Matrix对话中没有控制或失败的单点:与Matrix中其它地方的某人进行通信的行为,将与通信各方平等共享对话的所有权。即使后台服务器脱机,对话也可以在其他地方继续不间断,直到服务器恢复为止。

    这意味着每台服务器都对其用户数据拥有完全的自主权,任何人都可以选择或运行自己的服务器并参与更广泛的Matrix网络。这就是Matrix对通信控制方式的民主化。这个动图演示了多个用户之间如何进行消息复制和通话。

    等等,这怎么越听越耳熟?这机制不就是区块链吗?

    Matrix和Blockchain


    虽然官网没找到任何与Blockchain区块链的关联,但还是挖出2018年的一则新闻《Status向Matrix投资500万美元创建区块链即时通讯软件》

    Status是完全基于p2p点对点技术构建的以太坊移动客户端。 其同名公司Status于2018年1月宣布对Matrix.org背后的商业公司New Vector进行重大投资,该公司是安全和去中心化通信的开放标准。该公司于2017年通过SNT代币销售在不到24小时的时间内成功筹集了超过1亿美元的资金。

    Status创始人说,“我们现有的通信和数据存储系统依靠这种中心化,但是分散的去中心化替代方案正在出现,并且可以解决以前那些缺点。我设想我们将进入一个世界,通信采用点对点协议进行操作,从而为个人和机构带来更高的安全性,并拥有更强的隐私性,我们从而可以在所有计算接口上保持说话的自由。“

    合作将在Matrix和以太坊自己的实时通信协议Whisper之间架起一座桥梁,并允许Status App作为小插件集成到Riot.im中。它还允许使用Status的网络代币,从而在Riot.im中启用加密货币支付机制。

    Riot

    一个基于Matrix通讯标准开发的跨平台客户端App,开源。 

    3其它框架&平台

    再把Matrix德国其它政府机构目前正在测试的Stashcat,XMPP,Wire和Threema通讯框架相比。

    Stashcat

    位于汉堡的德国本土公司开发的跨平台即时通讯框架,客户面向公司和政府部门,商业闭源,收费。 

    价格感人,多于10用户,每人每月3.9欧。官方称已有50万用户,其中包括德国下萨克森州警察局的25000名警察,该警局年费不会低于1200万欧。德国政府恐怕不会把Stashca作为全德联邦政府通讯软件首选,太贵了......   


    XMPP

    XMPP(Extensible Messaging and Presence Protocol)是一种基于标准通用标记语言的子集XML的协议,该协议应该也不会被考虑广泛使用,所有信息通过XML格式传输,包括转成Base64的数据和图片,实在是太陈旧了......

    Wire

    公司总部位于瑞士,在柏林和旧金山有分部,一个跨平台即时通讯框架。客户为全球500强以及NGO,项目开源,但商用收费。 

    其中Wire Pro适用于机构和社区,Wire Enterprise适用政府和公司,Pro每人每月4欧,Enterprise每人每月8欧。这比Stashcat还贵。德国政府若是全面采用,恐怕得破产。

    Threema

    瑞士公司开发的跨平台的即时通讯软件。官宣有500万私人用户以及200万于3000家公司的商业用户,项目部分开源(仅仅部分通讯协议开源)。   

    普通用户只需在App商店一次性付费下载,就可以永久免费使用。但如果用于政府,公司或者组织,则通过其Threema Broadcast广播服务,Threema Gateway和Threema Work群组协作等服务收费。其中Broadcast广播服务收费标准不贵。

    4花落谁家

    这么比较下来,在加密安全性,通讯标准上这几个平台不会差太多,除了Matrix之外都是基于中心化服务。表面上算下来开源的Matrix不要钱,但Matrix背后的商业公司New Vector提供的专业咨询可不是免费的。技术上始终有如下疑问:

    1. 即时通讯系统去中心化,每个节点都承担消息存储的繁重任务,真能承受多用户海量聊天数据的高并发吗?

    2. 多节点之间备份和复制所有节点所有用户的消息,文本信息倒是没关系,但是数据呢,比如动图表情,视频,语音等数据,几千用户每人随便上传一个几mb的文件会不会就要拖垮绝大多数节点?

    3. 去中心化是噱头还是刚需?也许在战时为了保证单一服务器被攻击,而多节点可以保证基本通讯的畅通?

    德国政府请来的IT顾问们,今年应该头很大。

     参考

    https://www.golem.de/news/open-source-bundeswehr-testet-chat-app-auf-basis-von-matrix-1912-145749.html

    https://matrix.org/ 

    https://medium.com/@RiotChat/the-big-1-0-68fa7c6050be 

    https://venturebeat.com/2018/01/29/status-invests-5-million-in-matrix-to-create-a-blockchain-messaging-superpower/

    https://threema.ch/  

    德国政府计划开发自己的即时通讯App替代Whatspp

    新闻&文章回顾

    可向下滑动

    疫情之下德国公司纷纷裁员,程序员呢?

    Zalando在疫情中成为赢家,甚至超越了亚马逊

    德国清真银行初创,没有武器、博彩和毒品交易

    德国奔驰Instagram账号被黑

    疫情期间,德国外卖行业突然受宠

    14亿人的战争:中国人用了30年望见计算力的珠峰

    [甜猫de故事] 签证两周到期,没有德国文凭的我,如何拿到Offer?

    德国疫情控制追踪App,合约已签,我不想再吐槽了

    [甜猫de故事]从德语专业跨行德国IT界

    用手机通过一个App为新冠药物研究贡献算力

    SAP德国华人向数家养老院/医疗机构捐赠物资

    11个问题,帮你彻底搞懂工业互联网

    疫情对德国各行业门店客流的影响巨大

    德国史上最贵交规不用怕,老司机们最后的福音

    2020.04新闻&文章回顾

    2020.03新闻&文章回顾

    2020.02新闻&文章回顾

    2020.01新闻&文章回顾


    展开全文
  • WEB即时通讯/消息推送

    万次阅读 多人点赞 2017-03-09 22:12:04
    通常进行的Web开发都是由客户端主动发起的请求,然后服务器对请求做出响应并返回给客户端。但是在很多情况下,你也许会希望由服务器主动对客户端发送一些数据。 那么,该如何实现这个需求,或者说该如何向网页推送...

    写在前面

    通常进行的Web开发都是由客户端主动发起的请求,然后服务器对请求做出响应并返回给客户端。但是在很多情况下,你也许会希望由服务器主动对客户端发送一些数据。

    那么,该如何实现这个需求,或者说该如何向网页推送消息呢?

    一、推送方式


    我们知道,HTTP/HTTPS协议是被设计基于“请求-相应”模型的,尽管HTTP/HTTPS可以在任何互联网协议或网络上实现,但这里我们只讨论在Internet网上的万维网中的情况。

    由于在Internet中,HTTP协议在传输层使用的是TCP协议。由此可知,只要我们能保持TCP连接不随一次“请求-响应”结束而结束,使得服务器可以主动发送数据,那么我们就能够实现向网页的数据推送。事与愿违,在2011年WebSocket(详见下文)出现之前我们对此是无能为力的。

    不过,在那时虽然不能直接实现推送,但是还是有曲线救国路线的,基本上有4类这种间接方式。当然现在我们还有了1种直接方式-WebSocket ,接下来我来依次介绍下。


    模拟推送

    1. 轮询(Polling)

    AJAX 定时(可以使用JS的 setTimeout 函数)去服务器查询是否有新消息,从而进行增量式的更新。这种方式间隔多长时间再查询是个问题,因为性能和即时性是反比关系。间隔太短,海量的请求会拖垮服务器,间隔太长,服务器上的新数据就需要更长的时间才能到达客户机。

    • 优点:服务端逻辑简单;
    • 缺点:大多数请求是无效请求,在轮询很频繁的情况下对服务器的压力很大;

    所以,除了一些简单练习项目外,这种方式不能被用于生产。


    Comet

    2和3属于:Comet (web技术),是广大开发者想出来的比较可行的推送技术。

    2. 长轮询(Long-Polling)

    客户端向服务器发送AJAX请求,服务器接到请求后hold住连接,直到有新消息或超时(设置)才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。

    • 优点:任意浏览器都可用;实时性好,无消息的情况下不会进行频繁的请求;
    • 缺点:连接创建销毁操作还是比较频繁,服务器维持着连接比较消耗资源;

    微信网页版使用的就是这种方式,据我观察:

    • 微信把25秒作为超时时间;
    • 用两个请求来完成长轮询,一个用于25秒超时获取是否有新消息,当有新消息时会用另一个AJAX请求来获取具体数据。

    这种方式是可以被用于生产的,并且已经被实践检验有比较高的可用性。

    3. 基于iframe的方式

    iframe 是很早就存在的一种 HTML 标记, 通过在 HTML 页面里嵌入一个隐蔵帧,然后将这个隐蔵帧的 src 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。
    这里写图片描述

    iframe 服务器端并不返回直接显示在页面的数据,而是返回对客户端 Javascript 函数的调用,如<script type="text/javascript">js_func("data from server")</script>。服务器端将返回的数据作为客户端 JavaScript 函数的参数传递;客户端浏览器的 Javascript 引擎在收到服务器返回的 JavaScript 调用时就会去执行代码。

    每次数据传送不会关闭连接,连接只会在通信出现错误时,或是连接重建时关闭(一些防火墙常被设置为丢弃过长的连接, 服务器端可以设置一个超时时间, 超时后通知客户端重新建立连接,并关闭原来的连接)。

    • 优点:消息能够实时到达;
    • 缺点:使用 iframe 请求一个长连接有一个很明显的不足之处:IE、Morzilla Firefox 下端的进度栏都会显示加载没有完成,而且 IE 上方的图标会不停的转动,表示加载正在进行;

    Google公司在一些产品中使用了iframe流,如Google Talk。


    局限性方式

    4. 插件提供的Socket方式

    利用Flash XMLSocket,Java Applet套接口,Activex包装的socket。

    • 优点:原生socket的支持,和PC端和移动端的实现方式相似;
    • 缺点:浏览器端需要装相应的插件;

    5. WebSocket

    2011年,WebSocket被IETF定为标准RFC 6455,WebSocket API也被W3C定为标准。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

    WebSocket自然是极好的,更多细节我在下一节详细说明。


    到这里,我们已经对WEB上的消息推送机制有了一个整体的了解。不过,仅仅只有了解对于我们来说显然还不够,由于我是Java程序员,接下来我将继续介绍WebSocket,并且用Java做服务端来做一个例子。


    二、WebSocket

    WebSocket 是独立的、创建在 TCP 上的协议。Websocket 通过 HTTP/1.1 协议的101状态码进行握手。为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(handshaking)。

    1. ws请求

    一个典型的WebSocket请求如下:

    GET wss://xxx.xxx.com/push/ HTTP/1.1
    Host: xxx.xxx.com:port
    Connection:Upgrade
    Upgrade:websocket
    Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
    Sec-WebSocket-Key:rZGX8zZKTrdkhIJTCuW54Q==
    Sec-WebSocket-Version:13
    
    // Connection必须为:Upgrade,表示client希望升级连接;
    // Upgrade必须为:websocket,表示client希望升级到Websocket协议;
    // Sec-WebSocket-Key:是随机字符串,服务端会将其做一定运算,最后在Response中返回“Sec-WebSocket-Accept”头的值。用于避免普通http请求被当做WebSocket协议。
    // Sec-WebSocket-Version:表示支持的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均应当被弃用。

    响应如下:

    HTTP/1.1 101 Switching Protocols
    Upgrade:websocket
    Connection:upgrade
    Sec-WebSocket-Accept:QJsTRym36zHnArQ7FCmSdPhuK78=
    
    // Connection:upgrade 升级被服务器同意
    // Upgrade:websocket 指示客户端升级到websocket
    // Sec-WebSocket-Accept:参考上面请求的Sec-WebSocket-Key的注释

    上面只是比较重要的点,其实只知道这些暂时就够了,更详细的细节请参看:
    RFC 6455 WebSocket
    wikipedia WebSocket

    2. WebSocket在Java中

    JavaEE 7的JSR-356:Java API for WebSocket,已经对WebSocket做了支持。不少Web容器,如Tomcat、Jetty等都支持WebSocket。Tomcat从7.0.27开始支持WebSocket,从7.0.47开始支持JSR-356。

    但是如果使用Java EE的WebSocket API的话,还有很多自己需要封装的地方。所以接下来我要说的并不是Java官方的API,而是目前正在接触的一种推送框架:Socket.IO以及其Server端的Java实现netty-socketio。这个框架不仅支持WebSocket,还支持Long-Polling模式。

    注意Socket.IO并不是一个标准的WebSocket的实现,只是说Socket.IO使用并很好的支持了WebSocket协议而已。

    下面就说一下这两个框架。

    3. SOCKET.IO

    Socket.IO enables real-time bidirectional event-based communication. It consists in:

    SOCKET.IO - 官网地址
    SOCKET.IO - github地址

    由于其Server端是用Node.js实现的,又没有提供Java版本的Server,所以我找到了一个比较流行的第三方实现:netty-socketio。

    4. netty-socketio

    netty-socketio - github地址

    This project is an open-source Java implementation of Socket.IO server. Based on Netty server framework.

    netty-socketio是一个开源的Socket.IO Server的Java实现,基于Netty。

    接下来我就使用netty-socketio来做一个demo。


    三、netty-socketio实例

    建议先大致读一下Socket.IO和netty-socketio的官方网站相关信息,以有个整体的概念,然后再做Demo,我就不把那些搬过来了。

    Socket.IO中的一些重要概念。

    1. Server:代表一个服务端服务器;

    2. Namespace:一个Server中可以包含多个Namespace。见名知意,Namespace代表一个个独立的空间。

    3. Socket/Client:基本上这两个词是一个概念。

      • JavaScript客户端叫Socket,在创建时必须确定加入哪个Namespace,使用Socket可以让你和服务器通信。注意这个和伯克利Socket是不同的,只是开发者借用了一样的名字、功能相似。
      • Java服务端用Client来表示连接上服务器的链接,它就代表了JavaScript连接时创建的那个Socket
    4. room:在服务端,一个Namespace中你可以创建任意个房间,房间就是给Client进行分组,以进行组范围的通信。Client可以选择加入某个房间,也可以不加入。

    代码实例:两个Namespace,广播通讯。

    1. Java服务端

      public static void main(String[] args) throws InterruptedException {
      
      Configuration config = new Configuration();
      config.setHostname("localhost");
      config.setPort(9092);
      
      // 可重用地址,防止处于重启时处于TIME_WAIT的TCP影响服务启动
      final SocketConfig socketConfig = new SocketConfig();
      socketConfig.setReuseAddress(true);
      config.setSocketConfig(socketConfig);
      
      final SocketIOServer server = new SocketIOServer(config);
      final SocketIONamespace chat1namespace = server.addNamespace("/chat1");
      chat1namespace.addEventListener("message", ChatObject.class, new DataListener<ChatObject>() {
          @Override
          public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
              // broadcast messages to all clients
              chat1namespace.getBroadcastOperations().sendEvent("message", data);
          }
      });
      
      final SocketIONamespace chat2namespace = server.addNamespace("/chat2");
      chat2namespace.addEventListener("message", ChatObject.class, new DataListener<ChatObject>() {
          @Override
          public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
              // broadcast messages to all clients
              chat2namespace.getBroadcastOperations().sendEvent("message", data);
          }
      });
      
      server.start();
      
      Thread.sleep(Integer.MAX_VALUE);
      
      server.stop();
      }
      
    2. JS客户端

      引用到的JS文件:

      js文件github下载页面
      时间格式化JS

      <!DOCTYPE html>
      <html>
      <head>
          <title>Demo Chat</title>
          <link href="bootstrap.css" rel="stylesheet">
      <style>
      body {
          padding: 20px;
      }
      .console {
          height: 400px;
          overflow: auto;
      }
      .username-msg {
          color: orange;
      }
      .connect-msg {
          color: green;
      }
      .disconnect-msg {
          color: red;
      }
      .send-msg {
          color: #888
      }
      </style>
      
      <script src="js/socket.io/socket.io.js"></script>
      <script src="js/moment.min.js"></script>
      <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
      
      <script>
          var userName1 = 'user1_' + Math.floor((Math.random() * 1000) + 1);
          var userName2 = 'user2_' + Math.floor((Math.random() * 1000) + 1);
      
          var chat1Socket = io.connect('http://localhost:9092/chat1');
          var chat2Socket = io.connect('http://localhost:9092/chat2');
      
          function connectHandler(parentId) {
              return function() {
                  output('<span class="connect-msg">Client has connected to the server!</span>', parentId);
              }
          }
      
          function messageHandler(parentId) {
              return function(data) {
                  output('<span class="username-msg">' + data.userName + ':</span> '
                          + data.message, parentId);
              }
          }
      
          function disconnectHandler(parentId) {
              return function() {
                  output('<span class="disconnect-msg">The client has disconnected!</span>', parentId);
              }
          }
      
          function sendMessageHandler(parentId, userName, chatSocket) {
              var message = $(parentId + ' .msg').val();
              $(parentId + ' .msg').val('');
      
              var jsonObject = {'@class': 'com.ddupa.service.push.model.ChatObject',
                      userName: userName,
                      message: message};
              chatSocket.json.send(jsonObject);
          }
      
          chat1Socket.on('connect', connectHandler('#chat1'));
          chat2Socket.on('connect', connectHandler('#chat2'));
      
          chat1Socket.on('message', messageHandler('#chat1'));
          chat2Socket.on('message', messageHandler('#chat2'));
      
          chat1Socket.on('disconnect', disconnectHandler('#chat1'));
          chat2Socket.on('disconnect', disconnectHandler('#chat2'));
      
          function sendDisconnect1() {
              chat1Socket.disconnect();
          }
      
          function sendDisconnect2() {
              chat2Socket.disconnect();
          }
      
          function sendMessage1() {
              sendMessageHandler('#chat1', userName1, chat1Socket);
          }
      
          function sendMessage2() {
              sendMessageHandler('#chat2', userName2, chat2Socket);
          }
      
          function output(message, parentId) {
              var currentTime = "<span class='time'>"
                      + moment().format('HH:mm:ss.SSS') + "</span>";
              var element = $("<div>" + currentTime + " " + message + "</div>");
              $(parentId + ' .console').prepend(element);
          }
      
          $(document).keydown(function(e) {
              if (e.keyCode == 13) {
                  $('#send').click();
              }
          });
      </script>
      </head>
      <body>
          <h1>Namespaces demo chat</h1>
          <br />
          <div id="chat1" style="width: 49%; float: left;">
              <h4>chat1</h4>
              <div class="console well"></div>
      
              <form class="well form-inline" onsubmit="return false;">
                  <input class="msg input-xlarge" type="text"
                      placeholder="Type something..." />
                  <button type="button" onClick="sendMessage1()" class="btn" id="send">Send</button>
                  <button type="button" onClick="sendDisconnect1()" class="btn">Disconnect</button>
              </form>
          </div>
      
          <div id="chat2" style="width: 49%; float: right;">
              <h4>chat2</h4>
              <div class="console well"></div>
      
              <form class="well form-inline" onsubmit="return false;">
                  <input class="msg input-xlarge" type="text"
                      placeholder="Type something..." />
                  <button type="button" onClick="sendMessage2()" class="btn" id="send">Send</button>
                  <button type="button" onClick="sendDisconnect2()" class="btn">Disconnect</button>
              </form>
          </div>
      </body>
      
      </html>
      

    到这里,我们学习了一个能用于生产的推送框架的基本使用。不过,以上只是一个简单例子,仅做引路入门,更多参考可以直接去官方网站找到,我再写就是赘述了:

    例外的一点是,由于分布式netty-socketio的部署方式文档中描述的不太清晰,且这部分实际中比较重要,我会在下面再继续描述下。


    四、分布式服务器实例

    1. 分布式环境下的问题

    在分布式部署环境下假设有3台服务器分别为:PushServer001PushServer002PushServer003。有3个Client连接上了服务器且他们都在一个命名空间下的同一个room中(叫room1)。连接关系如下:

    • Client1 <———> PushServer001
    • Client2 <———> PushServer001
    • Client3 <———> PushServer003

      这里写图片描述

    此时Client1发送了一条消息,PushServer集群收到消息后显然需要将其推到Client2Client3上。

    • Client2好说:它和Client1连接的是同一个PushServer001PushServer001通过Client1可以获取到room,继而通过room获取到其下的所有Clients(其中必有Client2),然后推送即可。

    • Client3怎么办呢?它连接的是PushServer003,而003并没有收到Client1的推送事件。

    2. 解决方案

    其实解决方案也很简单,就是用发布/订阅 模式。

    1. 首先需要引入一个第三方的发布/订阅系统,比如这里使用Redis-PUB/SUB(如果Redis是主从复制的,注意PUB只能由Master做,SUB则Master和Slaves都行)

    2. 其次,每当服务器需要发送消息时:

      • 先将消息发送给本Server保存的某room中的所有Client
      • 接着再立即发布一个通知,例如叫PubSubStore.DISPATCH,并将消息内容放入其中。
      // 本服务器推送
      try {
          Iterable<SocketIOClient> clients = pushNamespace.getRoomClients(room);
          for (SocketIOClient socketIOClient : clients) {
              socketIOClient.send(packet);
          }
      } catch (Exception e) {
          logger.error("当前服务直接推送失败", e);
      }
      
      // 分发消息(当前服务不会向client推送自己分发出去的消息)
      try {
          pubSubStore.publish(PubSubStore.DISPATCH, new DispatchMessage(userId, packet, pushNamespace.getName()));
      } catch (Exception e) {
          logger.error("分发消息失败", e);
      }
    3. 最后,每台服务器启动时都订阅通知PubSubStore.DISPATCH。每当当前服务器收到此类订阅通知时,就将其中的消息分发到同一个房间名的所有Client去。在com.corundumstudio.socketio.store.pubsub.BaseStoreFactory.init(*)时:

      pubSubStore().subscribe(PubSubStore.DISPATCH, new PubSubListener<DispatchMessage>() {
          @Override
          public void onMessage(DispatchMessage msg) {
              String room = msg.getRoom();
              namespacesHub.get(msg.getNamespace()).dispatch(room, msg.getPacket());
          }
      }, DispatchMessage.class);

      如此便能解决此问题。附上netty-socket.io相关话题Wiki:How-To:-create-a-cluster-of-netty-socketio-servers


    其它一些事

    1. HTTP持久连接

    所谓HTTP持久连接即是:HTTP persistent connection,意即TCP连接重用技术。HTTP 1.0 的连接本来是“短连接”:建立一次TCP做完请求-响应即关闭,这样频繁的创建、关闭TCP连接显然是很低效比较浪费资源。

    所以HTTP协议后来就做了升级,允许使用一个请求和响应头Connection:keep-alive,来祈使服务器能够保持连接不中断。如此,一个TCP连接就能在你对同一个网站进行访问的时候被多次复用,请求网页HTML本身、网页中的JS、CSS和图片等都用这一个连接。

    不过,到了HTTP 1.1 以上连接默认就是持久化的了。

    值得注意的是HTTP服务器一般都有超时机制,服务器不可能容忍你一直不释放连接的。例如:Apache httpd 1.3/2.0是15秒、2.2是5秒。

    持久连接做的是连接复用的工作,并不是解决全双工通讯、推送的。

    展开全文
  • webim--web即时通讯的实现

    千次阅读 2018-12-18 14:33:01
    web浏览器端im的实现(web浏览器端的即时通讯系统)。 目录 http如何像tcp一样实时的收消息? 一、webim如何实现消息推送 二、人们为什么会误解http长轮询不实时 三、长轮询实际怎么玩 四、结论 初次接触web...
  • WEB即时通讯技术

    千次阅读 2020-12-05 11:23:43
    一:传统WEB通讯的原理 浏览器本身作为一个瘦客户端,不具备直接通过系统调用来达到和处于异地的另外一个客户端浏览器通信的功能。这和我们桌面应用的工作方式是不同的,通常桌面应用通过socket可以和远程主机上另外...
  • IM即时通讯-推荐框架

    千次阅读 2021-03-08 16:26:32
    CIM是一套基于mina或netty框架下的推送系统,或许有一些企业有着自己一套即时通讯系统的需求那么CIM为您提供了一个解决方案,目前CIM支持websocket,android,ios,桌面应用,系统应用等多端接入支持,可应用于移动...
  • 使用SSM框架整合websocket实现即时通讯功能,可以实现私聊和群聊,里面附带mysql数据库脚本
  • 基于GO语言实现的web客服即时通讯与客服管理系统。非常适合给自己的网站增加在线客服功能,代码简单也适合学习。 Github地址:https://github.com/taoshihan1991/go-fly 后台管理地址:...
  • Socket.IO 本是一个面向实时 web 应用的 JavaScript 库,现在已成为拥有众多语言支持的Web即时通讯应用的框架。 Socket.IO 主要使用WebSocket协议。但是如果需要的话,Socket.io可以回退到几种其它方法,例如Adobe ...
  • Web即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web即时通讯方案大致有4种:传统Ajax短轮询、Comet技术、WebSocket技术、SSE(Server-sent Events)。本文将简要介绍这4种技术的...
  • **即时通讯(IM)**是RDIFramework.NET敏捷开发框架全新提供的一个基于Web即时通讯、内部聊天沟通的工具。界面美观大方对于框架内部进行消息的沟通非常方便。基于RDIFramework.NET敏捷开发框架即时通讯IM支持...
  • 极光用于web通信(java后端+js前端) 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法...
  • **即时通讯(IM)**是RDIFramework.NET敏捷开发框架全新提供的一个基于Web即时通讯、内部聊天沟通的工具。界面美观大方对于框架内部进行消息的沟通非常方便。基于RDIFramework.NET敏捷开发框架即时通讯IM支持...
  • Web即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web即时通讯方案大致有4种:传统Ajax短轮询、Comet技术、WebSocket技术、SSE(Server-sent Events)。本文将简要介绍这4种技术的...
  • Web即时通讯、消息推送的实现

    万次阅读 2017-08-31 20:29:21
    Web即时通讯、消息推送的实现
  • 基于web 的应用程序的工作方式。使用客户端从服务器端获取一持续的信息主要有两种方式。 一是http长连接,很长时间以来,国内外的程序员都在对web服务如何实现长连接推送进行研究,但一直进展缓慢,这主要是由于两...
  • 在文章的开头,我要解释一下,为什么不直接使用web Socket实现即时通讯,因为一部分浏览器并不兼容web Socket,导致即时通讯在这些浏览器上无法正常使用,所以才需要用到nodeJs里封装好webSocket协议的socket.io包...
  • Web即时通讯技术原理详解

    千次阅读 2019-03-08 17:28:27
    有关IM(InstantMessaging)聊天应用(如:微信,QQ)、消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为流行,而网上关于原生IM(相关文章请...
  • 近来笔者接到公司的一个IM开发需要,要在原来的Web业务系统、移动端系统上加入一个即时聊天的功能,具有就是能聊天就行。相信各位也会接到需要开发IM的系统的任务,那么,开发一个im系统应选用哪种通讯协议? 2.思考-...
  • 有关IM(InstantMessaging)聊天应用(如:微信,QQ)、消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为流行,而网上关于原生IM(相关文章请...
  • 16.java websocket 即时通讯技术,点对点,群聊,单聊 17.新增Lucene 全文检索 18.Base64传输图片 19.图片加水印(图片水印,文字水印) 20.生成 or 解析 二维码 21.HTML5 + JAVAEE WebSocket 通信...
  • .net 网页即时通讯,包括前端即时通讯框架,包括websocket服务端。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,892
精华内容 5,156
关键字:

web即时通讯框架