Vert.x Web模块(六)

2023-11-15



SockJS

SockJS是一个客户端JavaScript库和协议,SockJS提供类似WebSocket的接口,此接口允许与SockJS服务器建立连接,而不论浏览器或者网络允许真实的WebSocketsSockJS通过支持浏览器与服务间的多样传输来完成这样工作。并在运行时根据浏览器和网络的能边选择其中之一。所有这一切对你都是透明的,你只简单看到类似WebSocket接口的工作方式。

为了获取更多关于SockJS的信息,请参考SockJS网站。

 

SockJS处理器

Vert.x提供一个创新的处理器叫SockJSHandler,便于在Vert.x-Web应用中使用SockJS。用SockJSHandler.create方法为每个SockJS应用创建一个处理器。在创建实例时也可以指定配置选项。配置选项由SockJSHandlerOptions类来描述。

Router router = Router.router(vertx);

 

SockJSHandlerOptions options = newSockJSHandlerOptions().setHeartbeatInterval(2000);

 

SockJSHandler sockJSHandler = SockJSHandler.create(vertx,options);

 

router.route("/myapp/*").handler(sockJSHandler);

 

处理SockJSSocket

在服务端,设置一个SockJS处理器,此处理器在每个客户端连接时都会被调用。调用时SockJSSocket类会被传入处理器。此类有着与socket类似的接口,与NetSocket或者WebSocket一样,可以读取和写入。其也实现了ReadStreamWriteStream两种流,所以可以将其泵接到其他读/写流。这是一个简单的SocketJS处理器的例子,简单地将读到的数据写回。

Router router = Router.router(vertx);

 

SockJSHandlerOptions options = newSockJSHandlerOptions().setHeartbeatInterval(2000);

 

SockJSHandler sockJSHandler = SockJSHandler.create(vertx,options);

 

sockJSHandler.socketHandler(sockJSSocket -> {

 

  // Just echo thedata back

 sockJSSocket.handler(sockJSSocket::write);

});

 

router.route("/myapp/*").handler(sockJSHandler);

 

客户端

客户端,使用SockJS客户端JavaScript库进行连接。可以从这里下载http://cdn.sockjs.org/sockjs-0.3.4.js,最小化版本可以从这里下载http://cdn.sockjs.org/sockjs-0.3.4.min.js。使用SockJS JavaScript客户端的详细信息可以参见SockJS官网https://github.com/sockjs/sockjs-client,总得来说,基本象下面代码一样使用:

var sock = new SockJS('http://mydomain.com/myapp');

 

sock.onopen = function() {

 console.log('open');

};

 

sock.onmessage = function(e) {

  console.log('message',e.data);

};

 

sock.onclose = function() {

 console.log('close');

};

 

sock.send('test');

 

sock.close();

 

配置SockJS处理器

使用SockJSHandlerOptions可以将多个选项配置给处理器。

  • insertJSESSIONID

    插入一个JSESSIONIDRcokkie,确保负载均衡器将指定SockJS会话的请求总是路由到正确的会话服务器。默认值为true.

  • sessionTimeout

    在客户端收到请求,服务器很长时间没有得到反馈时,服务 器发送一个关闭(close)事件。此处的延迟由此设置。在一个接收的连接在5秒种没有反映,默认的关闭事件将会被发送。

  • heartbeatInterval

    为了避免代理和负载均衡器关闭长时间运行的HTTP请求,需要保证连接是活的并且过一段时间发送心跳包。此设置用于设定发送心跳包的间隔。默认每隔25秒发送一个心跳包。

  • maxBytesStreaming

    多数流传输将响应保持在客户端并且不会释放投送消息的内存。这样的传输过一段时间需要进行垃圾回收。max_bytes_streaming设置了在流关闭时,单一http流请求所能传递的最小字节数。当到达此最小字节数时,客户端需要打开一个新请求。为了有效禁用流并且将流传输表现为轮询传输,请设置此值。默认值为128kb

  • libraryURL

    对于不支持跨域通信的传输,使用天然的iframe技巧。一个简单页面由SockJS服务器提供(使用外部域)并且将页面放置在不可见的iframe中。在此iframe中运行的代码不用担心跨域问题,因为由本地或运行,连接到SockJS服务器。此iframe不需要加载SockJS客户端库,此选项让你指定SockJS JavaScript库的url(如果不确定,默认地使用最新的最小化的socketJS客户端发行版)。默认值是http://cdn.sockjs.org/sockjs-0.3.4.min.js

  • disabledTransports

    这是禁用传输的列表。可能的值是WEBSOCKET,EVENT_SOURCE,HTML_FILE,JSON_P,XHR.

 

SockJS 事件总线桥

随同编译进Vert.x-WebSockJSsocket处理器叫事件总线桥,此处理器有效扩展服务端vert.x事件总线到客户端JavaScript中。这就创建了分布式事件总线,此事件总线不能跨越多个服务端Vert.x实例,但包括了运行在浏览器端的客户端JavaScript。因此,可以创建大的分布式总线压缩一些浏览器与服务器,只要服务器可连接,浏览器不必连接到相同的服务器。这是通过提供一个客户端JavaScript(vertx-eventbus.js)实现的,此JavaScript库提供了与服务端Vert.x事件总线相似的API,使用此API,可以发送和发布信息到事件总线并且可以注册处理器接收消息。此JavaScript库使用JavaScript SockJS客户端在SockJS连接上建立传输通道,在某个服务器端的处理器(SockJSHandler)终此连接。

一个特殖的SockJS socket处理器会添加到SockJSHandler,此处理器处理SockJS数据,或者将数据桥接到/自服务器端事件总线。为了激活格桥接,只要在SockJS处理器上简单调用bridge方法。

Router router =Router.router(vertx);

 

SockJSHandler sockJSHandler =SockJSHandler.create(vertx);

BridgeOptions options = newBridgeOptions();

sockJSHandler.bridge(options);

 

router.route("/eventbus/*").handler(sockJSHandler);

在客户端JavaScript中,需要使用 'vertx-eventbus.js`库创建到事件总线的连接发送和接收消息。

<scriptsrc="http://cdn.sockjs.org/sockjs-0.3.4.min.js"></script>

<scriptsrc='vertx-eventbus.js'></script>

 

<script>

 

var eb = newEventBus('http://localhost:8080/eventbus');

 

eb.onopen = function() {

 

 // set a handler to receive a message

 eb.registerHandler('some-address', function(error, message) {

    console.log('received a message: ' +JSON.stringify(message));

 });

 

 // send a message

 eb.send('some-address', {name: 'tim', age: 587});

 

}

 

</script>

此例子做的第一件事是创建一个事件总线实例:

var eb = new EventBus('http://localhost:8080/eventbus');

构造函数的参数是需要连接到的URI。因为我们创建带eventbus前缀的桥将会连到那里。在连接打开前,它实际还不能做任何事。打开连接时onopen处理器会被调用。

可以用依赖管理器获取客户端包。

Maven(pom.xml)

<dependency>

 <groupId>io.vertx</groupId>

 <artifactId>vertx-web</artifactId>

 <version>3.2.1</version>

 <classifier>client</classifier>

</dependency>

Gradle ( build.gradle):

compile 'io.vertx:vertx-web:3.2.1:client'

此库也可以用NPMBower获取。

注意,在3.0.03.1.0版本之间API已经改变了。请查看changelog。前一个版本的客户端被兼容仍然能被使用,但是新和客户端提供了更多特性并与vert.x事件总线API更接近。

 

保护SockJS

如果像上面例子一样打开一个没有保护的桥,并通过期试图发送消息,你将发现消息神奇地消失了。这发生了什么?

对于大多数应用,你或许不想客户端JavaScript发送一些消息到任何服务器端处理器或者其他所有的浏览器。例如,你在事件总线上有一个服务,此服务可访问或删除数据。我们不想错误行为或者恶意客户端删除所有数据库所有数据。我们也不想任意客户端侦听任意事件总线地址。为了处理上面问题,一个SockJS桥将默认拒绝传输任何消息。这取决于你告诉桥什么消息可以通过传输。对于总是能够通过的响应消息这是一个异常。换句话说,桥充当了防火墙角色,默认是拒绝所有(deny-all)策略。什么消息可以在桥上传输,只需对桥进行简单配置。

在调用桥时,可用传入BridgeOptions对出站和入站允许的流量进行匹配。每个匹配是一个PermittedOptions对象:

setAddress

这代表了一个确切的消息发送到的地址。如果想让消息基于此确切地址,可以使用此字段。

setAddressReges

这是一个匹配地址的正则表达式。如果让想消息基于正则表达式地址,可以使用此字段,如果设置了address字段,将忽视此字段。

setMatch

此允许消息基于其消息结构。匹配的任何字段必须存在于消息中,同时值是允许的。此仅能用于JSON消息。

 

如果是传入的消息(如,由客户端javaScript发送到服务器)在服务器收到时,Vert.x-Web会查看所有入站许可匹配。如果匹配,将允许通过。

 

如是是出站肖息在被发送到客户端之前,Vert.x-Web会查看出站许可匹配,如果匹配,将允许通过。

实际匹配规则如下:

如果设置了address字段,消息地址必须与指定的address地址精确匹配才被认为是匹配的。

如果不设置address字段而是设置addressRegex字段,消息地址的格式必须与address_re中的正则表达式匹配。

如果设置了match字段,消息结构必须匹配,结构匹配是检查看消息是否有存在匹配对象的所有字段和值。

这是一个例子:

Router router =Router.router(vertx);

 

SockJSHandler sockJSHandler =SockJSHandler.create(vertx);

 

 

// Let through any messages sentto 'demo.orderMgr' from the client

PermittedOptionsinboundPermitted1 = new PermittedOptions().setAddress("demo.orderMgr");

 

// Allow calls to the address'demo.persistor' from the client as long as the messages

// have an action field withvalue 'find' and a collection field with value

// 'albums'

PermittedOptions inboundPermitted2= new PermittedOptions().setAddress("demo.persistor")

    .setMatch(newJsonObject().put("action", "find")

        .put("collection","albums"));

 

// Allow through any message witha field `wibble` with value `foo`.

PermittedOptionsinboundPermitted3 = new PermittedOptions().setMatch(newJsonObject().put("wibble", "foo"));

 

// First let's define what we'regoing to allow from server -> client

 

// Let through any messagescoming from address 'ticker.mystock'

PermittedOptionsoutboundPermitted1 = new PermittedOptions().setAddress("ticker.mystock");

 

// Let through any messages fromaddresses starting with "news." (e.g. news.europe, news.usa, etc)

PermittedOptionsoutboundPermitted2 = newPermittedOptions().setAddressRegex("news\\..+");

 

// Let's define what we're goingto allow from client -> server

BridgeOptions options = newBridgeOptions().

    addInboundPermitted(inboundPermitted1).

    addInboundPermitted(inboundPermitted1).

    addInboundPermitted(inboundPermitted3).

    addOutboundPermitted(outboundPermitted1).

    addOutboundPermitted(outboundPermitted2);

 

sockJSHandler.bridge(options);

 

router.route("/eventbus/*").handler(sockJSHandler);

 

消息必须的认证信息

事件总线桥可用Vert.x-Web认证功能配置成要求消息必须认证,不论是桥的入站还是出站。

为了完成此工作,如前节所描述的,需要添加额外的match字段,此字段段决定针对匹配的消息必须提供什么权利。用setRequiredAuthority设置登录用户需要特定访问消息的权利。

这是一个例子:

PermittedOptions inboundPermitted= new PermittedOptions().setAddress("demo.orderService");

 

// But only if the user is loggedin and has the authority "place_orders"

inboundPermitted.setRequiredAuthority("place_orders");

 

BridgeOptions options = newBridgeOptions().addInboundPermitted(inboundPermitted);

对于被授权的用户,首先需要登录,然后需要特定权利。为了处理登录和确切授权,可以为Vert.x配置正常的认证处理器(auth handler)。例如:

Router router =Router.router(vertx);

 

// Let through any messages sentto 'demo.orderService' from the client

PermittedOptions inboundPermitted= new PermittedOptions().setAddress("demo.orderService");

 

// But only if the user is loggedin and has the authority "place_orders"

inboundPermitted.setRequiredAuthority("place_orders");

 

SockJSHandler sockJSHandler =SockJSHandler.create(vertx);

sockJSHandler.bridge(newBridgeOptions().

        addInboundPermitted(inboundPermitted));

 

// Now set up some basic authhandling:

 

router.route().handler(CookieHandler.create());

router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));

 

AuthHandler basicAuthHandler =BasicAuthHandler.create(authProvider);

 

router.route("/eventbus/*").handler(basicAuthHandler);

 

 

router.route("/eventbus/*").handler(sockJSHandler);

 

处理事件总线桥事件

如果在桥的事件出现后想得到事件通知,可以在调用bridge方法时提供一个处理器。不论什么时间桥事件出下,事件将会传给处理器进行处理,用BridgeEvet实例对桥事件进行描述。事件可以是下面任一类型:

SOCKET_CREATED

在创建SockJS socket时,产生此事件

SOCKET_CLOSED

SockJS socket关闭时,产生此事件

SEND

在一个消息试图被从客户端发送到服务器时,产生此事件。

PUBLISH

在一个消息被图被从客户端发布到服务器时,产生此事件。

RECEIVE

在消息从服务器传送到客户端时,产生RECEIVE事件。

REGISTER

在一个客户端试图注册一个处理器时,产生此事件。

UNREGISTER

在一个客户端试图解注册一个处理器时,产生此事件。

 

用事件的type方法获取事件类型,并且用getRawMessage方法查看原生事件消息。

原事消息是一个JSON对象,俱有以下结构:

{

 "type":"send"|"publish"|"receive"|"register"|"unregister",

 "address": the event bus address beingsent/published/registered/unregistered

 "body": the body of the message

}

 

事件也是一个Future对象。在完成事件处理,可以用true来结束Future,以便进一步进行处理。如果不想让事件被处理,可以用false来结束Future。这对于过滤桥上传输的消息或者进行细粒度的授权和度量很有用。这是一个例子,在这个例子中,我们拒绝了所有包售“Armadillos”单词的所有消息。

Router router =Router.router(vertx);

 

// Let through any messages sentto 'demo.orderMgr' from the client

PermittedOptions inboundPermitted= new PermittedOptions().setAddress("demo.someService");

 

SockJSHandler sockJSHandler =SockJSHandler.create(vertx);

BridgeOptions options = newBridgeOptions().addInboundPermitted(inboundPermitted);

 

sockJSHandler.bridge(options, be-> {

 if (be.type() == BridgeEventType.PUBLISH || be.type() ==BridgeEventType.RECEIVE) {

    if(be.getRawMessage().getString("body").equals("armadillos")){

      // Reject it

      be.complete(false);

      return;

    }

 }

 be.complete(true);

});

 

router.route("/eventbus").handler(sockJSHandler);

也可以修改原始信息,例如改变消息体。对于从客户端流入的消息,也可以向消息添加头,这是一个例子:

Router router =Router.router(vertx);

 

// Let through any messages sentto 'demo.orderService' from the client

PermittedOptions inboundPermitted= new PermittedOptions().setAddress("demo.orderService");

 

SockJSHandler sockJSHandler =SockJSHandler.create(vertx);

BridgeOptions options = newBridgeOptions().addInboundPermitted(inboundPermitted);

 

sockJSHandler.bridge(options, be-> {

 if (be.type() == BridgeEventType.PUBLISH || be.type() ==BridgeEventType.SEND) {

    // Add some headers

    JsonObject headers = newJsonObject().put("header1", "val").put("header2","val2");

    JsonObject rawMessage = be.getRawMessage();

    rawMessage.put("headers",headers);

    be.setRawMessage(rawMessage);

 }

 be.complete(true);

});

 

router.route("/eventbus").handler(sockJSHandler);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vert.x Web模块(六) 的相关文章

  • 如何从 Javascript 访问 Oracle Apex 变量?

    我正在使用 Oracle APEX 但不确定如何从外部 javascript 文件访问以下变量 该文件可能位于应用程序服务器上或存储在共享组件 gt 静态文件中 APP ID APP PAGE ID APP SESSION 如何从 java
  • 通过jquery在日期框中自动添加斜杠/符号[重复]

    这个问题在这里已经有答案了 我发现几个问题但没有答案 所以我问问题 如何添加自动斜杠 符号
  • 欺骗或禁用页面可见性 API

    页面可见性 API https developer mozilla org en US docs Web Guide User experience Using the Page Visibility API开始普遍用于在选项卡未处于焦点时
  • Three.js - 如何使用姿势估计数据为 3D 模型制作动画

    我正在尝试使用姿势估计坐标来对 Three js 中的装配模型进行动画处理 我正在使用的姿势估计技术提供了视频源中人物的实时 x y z 坐标 我正在尝试使用这些坐标相应地移动 3D 模型 我使用下面的代码 其中一些代码是我在相关问题的答案
  • 组织 jQuery/JavaScript 代码的最佳方式 (2013) [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 问题 这个答案之前已经回答过 但已经
  • 从提交的表单中获取值

    我有一个非常简单的表格
  • 如何使用 JavaScript 访问 runat="server" ASP 元素?

    似乎每个人都在这样做 在代码帖子等中 但我不知道如何 每当我尝试使用 JavaScript 操作 asp 元素时 我都会得到一个 element is null or document is undefined 等等错误 JavaScrip
  • 处理重叠 SVG 图层中的鼠标事件

    我正在使用 d3 js 构建地图可视化 我正在为美国各州和县绘制填充多边形 县的 SVG 图层位于州图层下方 状态已填充 但填充不透明度设置为 0 我认为 需要填充来捕获点击事件 我想捕获州级的点击事件 但我想捕获县级的鼠标悬停事件 但是
  • 如何跨页面播放背景音乐

    我已经读过这个问题 我知道它只能用框架来完成 我真的不想要全站点 AJAX 如何在多个 HTML 页面上播放背景音频 https stackoverflow com questions 4210370 how to play a backg
  • React 和 ES6 继承

    Note 这篇文章是在 React 不支持 ES6 v12 时发布的 我有一个 ES6 课程 class BaseClass getInitialState return message Hello render return div di
  • 如何检查 Node.js 中是否定义了变量?

    我正在用node js 编写一个程序 它实际上是js 我有一个变量 var query azure TableQuery 看起来这行代码有时没有执行 我的问题是 我怎样才能做到这样的条件 if this variable is define
  • 我想在数据表中使用 Div 结构而不是 Table。是否可以?

    我想用数据表 https datatables net 用div结构代替表格 目的是满足设计要求 有什么可能的方法或替代方案吗 不 您将无法执行此操作 Datatables 的核心仅适用于表格元素和子 thead tbody tfooter
  • 通过 javascript 从 获取点击坐标

    Example
  • 如何使我的网站兼容移动设备和平板电脑? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想让我现有的网站在手机 平板电脑上查看时自动调整 甚至在您在桌面上调整屏幕时自动调整 如果失败的话 如果太难 你有什么建议 我基本上
  • 使用 JS 从列表中删除最近的 元素的 URL

    所以我有一个网址列表 并且有删除按钮 图像按钮 当点击删除按钮时 按钮旁边的 url 必须从列表中删除 let list const remove document getElementById remove const view docu
  • Highcharts 异步服务器加载多个系列

    我正在尝试按照其示例使用 Highcharts 的延迟加载 http www highcharts com stock demo lazy loading http www highcharts com stock demo lazy lo
  • 自动打开默认电子邮件客户端并预填充内容

    当用户在页面上保存某些内容时 我需要自动打开用户的默认电子邮件客户端 我需要填充电子邮件主题 地址并在电子邮件正文中添加一些内容 实现这一目标的最佳选择是什么 我知道mailto 属性 但用户必须单击此属性 我不确定它是否允许您指定主题和内
  • 矩形描边上的单击事件

    我想仅在矩形的笔划上添加单击事件 并避免在矩形内部单击 下面是代码 var stage new Kinetic Stage container container width 578 height 200 var layer new Kin
  • Angular 4 - “等待操作”的正确方法是什么?

    我遇到了一个简单的问题 有一个很奇怪的解决方案setTimeout 0 看看这个简单的代码 Component selector my app template div div
  • 如何使用 javascript 获取 html5 视频的缩略图?

    我找到了根据 URL 获取视频缩略图的 JavaScript 代码 不过 我只在 YouTube 和 Vimeo 上找到了这个 似乎没有人列出如何处理旨在嵌入 html5 视频标签的视频的示例 能做到吗 谢谢 是的 您可以使用视频作为画布的

随机推荐

  • 计算机图形学GAMES101(十五)光线追踪(蒙特卡洛积分与路径追踪)

    本节涉及内容 蒙特卡罗积分 路径追踪 蒙特卡罗积分 蒙特卡罗积分的核心思想还是求一个不规则图形的面积 它的做法是 首先在a和b之间找一个值xi然后求f x 接着以f x 为高 ab为宽求矩形的面积 最后将所有的值求平均 当采样数量xi趋于无
  • C++斩题录

    个人主页 平行线也会相交 欢迎 点赞 收藏 留言 加关注 本文由 平行线也会相交 原创 收录于专栏 手撕算法系列专栏 LeetCode 本专栏旨在提高自己算法能力的同时 记录一下自己的学习过程 希望对大家有所帮助 希望我们一起努力 成长 共
  • 华南技术栈CNN+Bilstm+Attention

    我的目标适用于文本分类 这里有一个 技术栈完全一样但是目标不一样的应该可以参考 现在的情况 2022年7月6日21 16 04已解决 换成了CPU 因为电脑太破旧了 cuda跟不上pytorch官网 已安装 cuda cudnn anaco
  • 兼阅万分享:适合上班族下班时间做的6项兼职小副业

    你的收入还在8000以下 车贷 房贷 孩子学费 兴趣班费用要交 开车油门踩深点 都会心疼油费 每个月的压力都很大 白天要干活 有没有适合晚上下班后做的兼职或者副业 今天推荐6项 可以保存下来 如果真的撑不住了 挑一个干 虽然发不了大财 但改
  • python提高办公效率-【纯干货】提高Python运行效率的小窍门

    Python是一门优秀的语言 它能让你在短时间内通过极少量代码就能完成许多操作 不仅如此 它还轻松支持多任务处理 比如多进程 不喜欢Python的人经常会吐嘈Python运行太慢 但是 事实并非如此 尝试以下六个窍门 来为你的Python应
  • 爬虫日常练习-selenium登录12306

    文章目录 前言 页面分析 代码设计 前言 hello 好兄弟们 经过前面几篇文章后 想必小伙伴们对于简单的网页文本爬取 图片爬取类的内容已经熟练掌握了 今天我们开始练习一个新的内容 selenium 有关这一块的基础知识网上太多了 我们作为
  • 微信小程序如何测试?

    不需要安装 只要在微信里找到这个小程序打开即可使用 由于小程序的便捷 如今越来越多的平台开发方都纷纷推出自身的小程序应用 那我们该如何进行微信小程序测试呢 1 功能测试 功能测试以需求文档和交互视觉文档为准 如果没有这些文档 参考APP的测
  • 卷积神经网络的评价_金工研报:利用卷积神经网络进行多因子选股

    写在前面 下面这篇文章的内容主要来自华泰证券的研究报告 人工智能选股之卷积神经网络 文中首先通过对卷积神经网络 CNN 进行分析 然后通过将因子数据转换为二维图片的形式 并根据CNN原理给出了通过CNN运用于多因子选股的经验和方法 最后通过
  • map中取值转BigDecimal报错 java.lang.Integer cannot be cast to java.math.BigDecimal

    Map
  • Elasticsearch 中文分词&多词搜索&权重

    目录 中文分词器 一 安装中文分词器ik 二 使用中文分词器 多词搜索 权重 中文分词器 一 安装中文分词器ik 源码地址 https github com medcl elasticsearch analysis ik 根据提示 进行安装
  • HLS 流传输库hls::stream

    流传输数据是一种数据传输形式 其中数据样本从第一个样本开始按顺序发送 流传输不需要地址管理 Vivado HLS 提供了 C 模板类 hls stream lt gt 用于对流传输数据结构进行建模 使用 hls stream lt gt 类
  • 前端加密和解密

    Base64加密 加密 Base64 encode Base64 encode 解密 Base64 decode Base64 decode url携带参数加密 加密 encodeURLComponent encodeURLComponen
  • 【Unity】一个简单的无限列表

    1 根据InfiniteElem 的高度和总个数 计算出Content的长度 2 根据Content所在的滚动位置 计算出当前哪些InfiniteElem显示在列表中 3 循环是生成的几个InfiniteElem显示列表内容 实现无限列表
  • LeetCode-1827. 最少操作使数组递增【贪心,数组】

    LeetCode 1827 最少操作使数组递增 贪心 数组 题目描述 解题思路一 简单暴力 解题思路二 优化1 ans是操作数 mx是当前最大元素 mx无论如何会依次递增 解题思路三 优化2 遇到小的数就pre 1 否则变为num 题目描述
  • C# 文件上传

    获取POST 请求发送的文件 并保存到服务器 HttpPostedFile file System Web HttpContext Current Request Files file 获取上载文件名称 string FileName fi
  • SoapUI、Jmeter、Postman三种接口测试工具的比较分析

    前段时间忙于接口测试 也看了几款接口测试工具 简单从几个角度做了个比较 拿出来与诸位分享一下 本文从多个方面对接口测试的三款常用工具进行比较分析 以便于在特定的情况下选择最合适的工具 或者使用自己编写的工具 不同工具定位不同 我们只是主要从
  • C语言之贪心算法疯牛

    疯牛 时间限制 1000 ms 内存限制 65535 KB 难度 4 描述 农夫 John 建造了一座很长的畜栏 它包括N 2 lt N lt 100 000 个隔间 这些小隔间依次编号为x1 xN 0 lt xi lt 1 000 000
  • Vant--移动端组件库

    Vant 是一个轻量 可靠的移动端组件库 于 2017 年开源 目前 Vant 官方提供了 Vue 2 版本 Vue 3 版本和微信小程序版本 并由社区团队维护 React 版本和支付宝小程序版本 文章目录 目录 文章目录 前言 一 优势
  • 轻松玩转Windows系统自带远程桌面及如何处理“出现了内部错误““0x4““0x7“等错误提示

    现在网络上的第三方远程协助软件很多 包括向日葵 ToDesk等等 但是 如果你遇到只有内网的情况下 或者外网速很差很慢 比如学校 或者禁止连外网的单位等等 使用第三方远程协助就很卡 甚至成了摆设 这种情况下 我们就需要用到Windows系统
  • Vert.x Web模块(六)

    SockJS SockJS是一个客户端JavaScript库和协议 SockJS提供类似WebSocket的接口 此接口允许与SockJS服务器建立连接 而不论浏览器或者网络允许真实的WebSockets SockJS通过支持浏览器与服务间