本文介绍如何使用IBM Integrated Web Application Server for i和IBM i上的Node.js在IBM i上创建WebSocket应用程序,以及如何将WebSocket应用程序与IBM HTTP Server for i关联。 一个简单的基于Web的IBM i控制台示例可以帮助您介绍和指导您使用Java和JavaScript创建WebSocket应用程序。 我们还可以探索建立HTTP Server环境的分步过程。
WebSocket规范是作为HTML5计划的一部分而开发的,并引入了WebSocket JavaScript接口,该接口定义了全双工单套接字连接,通过该接口可以在客户端和服务器之间发送消息。 WebSocket协议允许浏览器与网站之间进行实时交互,从而促进交互式实时内容。 例如,这可以用于创建实时游戏。 通过提供一种标准化的方法,使服务器无需向客户端请求每个请求就可以将内容发送到浏览器,并允许消息在保持连接打开的情况下来回传递,从而使之成为可能。 与Comet和Ajax相比,WebSocket代表了Web通信的下一步发展。
目前,大多数主流浏览器(包括Google Chrome,Microsoft®Internet Explorer,Mozilla Firefox,Safari和Opera)都支持WebSocket协议。 本文重点介绍在以下服务器端Web技术中使用WebSocket的方法。 它还说明了如何在简单的应用程序中配置和建立WebSocket连接。
- IBM Integrated Web Application Server for i是IBM i上基于Java的轻量级应用程序运行时。 根据WebSphere Application Server Liberty概要文件V8.5更新了最新版本。 Liberty概要文件是可组合的动态应用程序服务器,并提供对WebSocket 1.0和1.1的支持。
- Node.js是基于Google Chrome V8引擎的开源项目。 它为无需浏览器即可运行的服务器端JavaScript应用程序提供了一个平台。 现在在IBM i平台上支持Node.js。 它还提供对WebSocket的支持。 要开始在IBM i上使用Node.js,建议阅读这篇文章, 在IBM i上使用Node.js的本机JavaScript应用程序 。
- 适用于i的IBM HTTP Server(由Apache支持)是一个完整的Web服务器产品,它提供了多个组件和功能来协助您进行网站配置和开发。 借助用于i的IBM HTTP Server(由Apache支持),您可以快速拥有所需的一切,并且可以轻松地建立Web形象并在网络上运行您的业务。 在IBM i 7.2上,HTTP Server已升级到Apache 2.4.12,它引入了一个新模块
mod_proxy_wstunnel
。 这个新模块为将WebSocket连接隧道传输到后端WebSocket服务器提供了支持。 在IBM i 7.1上,用于i的IBM HTTP Server基于不提供WebSocket支持的Apache 2.2.11。
软件先决条件
为了使WebSocket应用程序成功与HTTP Server关联并在IBM i上运行,需要以下许可程序和程序临时修订(PTF)组。
所需的许可证程序:
- 5770SS1,选项30 – QSH
- 5770SS1,选项33 –便携式应用解决方案环境
- 5770DG1,* BASE –适用于i的IBM HTTP Server
- 5733OPS,选项1 – IBM i开源解决方案
- 5770JV1,选项14 – Java SE 7 32位
- 5733SC1,选项1 – OpenSSH,OpenSSL,zlib
所需的PTF组:
- 适用于i PTF组SF99713的IBM i 7.2 HTTP Server –级别12(或更高版本)
- IBM i 7.2 Java PTF组SF99716 –建议使用最新级别
- 适用于i PTF组SF99368的IBM i 7.1 HTTP Server –级别37(或更高版本)
- IBM i 7.1 Java PTF组SF99572 –建议使用最新级别
注 :IBM i 7.1和更高版本支持5733OPS。 如果需要为WebSocket隧道配置i的HTTP Server,则需要使用IBM i 7.2或更高版本。
在以下各节中,我们将创建三个单独的示例:
- WebSocket服务器端Java应用程序和客户端基于WebJavaScript应用程序
- JavaScript中的WebSocket服务器端应用程序
- IBM HTTP Server for i与WebSocket应用程序一起使用
下表提供了示例的测试环境。
表1.测试环境方案
情境 | 知识产权 | 非SSL端口 | SSL端口 | WebSocket URI |
---|---|---|---|---|
Liberty上的WebSocket服务器 | 192.168.0.101 | 10000 | 10443 | ws://192.168.0.101:10000 / WSConsole / CLRunner wss://192.168.0.101:10443 / WSConsole / CLRunner |
Node.js上的WebSocket服务器 | 192.168.0.102 | 8888 | 8889 | ws://192.168.0.102:8888 / CLRunner wss://192.168.0.102:8889 / CLRunner |
使用mod_proxy_wstunnel HTTP服务器 | 192.168.0.103 | 80 | 443 | ws://192.168.0.103/ws wss://192.168.0.103/wss |
在以下两节中,我们将演示两个示例,并提供详细步骤,以向您展示如何分别使用Java和Node.js创建和运行WebSocket Web应用程序。 在上一节中,我们演示了如何使用Apache 2.4提供的新的mod_proxy_wstunnel
模块将WebSocket示例与IBM i HTTP Server相关联。
在我们提供的WebSocket示例中,客户端在Web浏览器中输入控制语言(CL)命令。 CL命令发送到服务器以执行,结果返回到浏览器。 这可以通过使用传统的HTTP请求和响应来实现,但是在这里,我们向您展示了如何通过使用更高级的WebSocket技术来更轻松地做到这一点。
使用Java创建WebSocket服务器应用程序
本节说明了使用Java创建WebSocket服务器应用程序所需的步骤。 假定您熟悉使用Java开发环境创建基于Java的Web应用程序。
步骤1.设置所需的Java环境
仅Java EE 1.7和更高版本支持WebSocket。 因此,在您的开发系统上安装Java EE 1.7,并在开发工具中采用它,或将所需的javax.websocket-api-1.1.jar文件复制到您的开发环境中,并将其添加到类路径中。 .jar文件仅提供与WebSocket相关的接口,但不提供实现。 该实现由应用服务器提供。 完成设置后,在Java开发工具中创建一个Web应用程序项目。 推荐的开发工具包括Rational Developer for i,Rational Application Developer或基于Eclipse的标准工具。
步骤2.创建所需的Java类
使用内容创建WSConsoleServerEndPoint.java文件,如清单1所示。
清单1. Java中的WebSocket服务器实现
package com.ibm.ws.demo.server;
import java.io.IOException;
import java.net.InetAddress;
import java.util.logging.Logger;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.OnError;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import com.ibm.ws.demo.CLRunner;
@ServerEndpoint(value = "/CLRunner")
public class WSConsoleServerEndPoint {
private Logger logger = Logger.getLogger(this.getClass().getName());
@OnOpen
public void onOpen(Session session) {
logger.info("[Server] Connected. " + session.getId());
session.setMaxIdleTimeout(300000);
try {
InetAddress ia = InetAddress.getLocalHost();
session.getBasicRemote().sendText("[From Server] Connected to " + ia.getHostName() +
" [" + ia.getHostAddress() + "].");
} catch (IOException e) {
e.printStackTrace();
}
}
@OnMessage
public String onMessage(String message, Session session) {
logger.info("[Server] Received:" + message);
String result = CLRunner.runCL(message);
return result;
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
logger.info(String.format("[Server] Session %s closed because of %s", session.getId(),
closeReason));
}
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
}
该类是WebSocket服务器的实现。 Java使用注释来实现简单和简单的WebSocket实现。 除了Java代码,WebSocket服务器不需要任何配置。 以下代码行定义了WebSocket的URI。
@ServerEndpoint(value = "/CLRunner")
以下四个属性是WebSocket服务器框架。 当特定事件发生时,它们被称为。
表2. WebSocket对象属性
属性 | 描述 |
---|---|
OnOpen | 建立连接时调用 |
OnMessage | 收到消息时调用 |
OnClose | 断开连接时调用 |
OnError | 发生错误时调用 |
大多数WebSocket服务器的主要功能都是通过onMessage
方法实现的。 当客户端向服务器发送消息(通常是字符串)时 ,将调用此方法。 然后,服务器代码使用输入消息创建响应消息,然后由onMessage
方法返回该响应消息。
以下代码行用于设置WebSocket连接的超时。 如果达到超时,连接将在服务器端自动关闭。 客户端接收超时事件。
session.setMaxIdleTimeout(300000);
步骤3.为WebSocket客户端创建HTML文件
现在,我们使用JavaScript创建WebSocket客户端以访问WebSocket服务器。 您只需要创建一个WebSocket对象并为不同的WebSocket事件定义方法,如下面的清单所示。
清单2.创建和初始化WebSocket对象
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
下表中显示的三种方法由WebSocket对象提供。
表3. WebSocket对象方法
方法 | 描述 |
---|---|
WebSocket WebSocket(WSUrl) | 此方法创建一个WebSocket对象。 WSUrl是您需要连接的URL。 |
无效close() | 此方法关闭WebSocket连接或连接尝试(如果有)。 |
无效发送(数据) | 此方法通过WebSocket连接将数据传输到服务器。 数据是要发送到服务器的文本字符串。 |
在示例网页上,客户端从用户接收到CL命令。 然后,它使用send ()
方法将CL命令发送到服务器,如以下示例所示。
websocket.send(message);
附件中HTML文件WSConsole.html包含代码详细信息。 您可以在示例中下载并使用它。
步骤4.创建一个Integrated Web Application Server实例并为WebSocket设置环境
适用于i的IBM Web Administration( http:// <your.server.name&gt;:2001 / HTTPAdmin )可以轻松地用于创建i的Integrated Web Application Server实例。 请参阅IBM i知识中心,以获取有关如何为i V8.5创建Integrated Web Application Server实例的详细信息。 本文以一个名为INTAPPSVR的用于i V8.5实例的集成Web应用服务器为例。 它侦听端口10000,并且根目录为/ www / INTAPPSVR。
默认情况下,用于i的Integrated Web Application Server初始化为在IBM i 7.1和7.2上使用JDK 6。 这需要更新以使用JDK 7来使WebSocket正常工作。
启动IBM Web Administration for i,单击“ 应用程序服务器”选项卡,选择刚刚在服务器列表中创建的实例,然后单击左窗格中的“ 属性 ”。 在“ 应用程序服务器”选项卡上,“ Java主页”字段中列出了系统上安装的所有JDK。 从列表中选择JDK 7 32位,然后单击Apply 。
图1.将Integrated Web Application Server使用的JDK更改为Java版本7
单击“ 功能”选项卡,选择websocket-1.1功能并将其添加到“ 选定功能”列表中。
图2.添加websocket-1.1功能
然后,单击“ 应用”以使其生效。 默认情况下,实例中仅加载三个功能。 安全套接字层(SSL)配置需要功能ssl-1.0,在IBM Web Administration for i GUI中管理实例需要功能localConnector-1.0。 可以根据您的应用程序需求添加其他功能。
现在,服务器已更改,需要重新启动服务器才能使这些设置生效。 单击停止服务器
步骤5.部署WebSocket应用程序
从开发工具中将Web应用程序导出为war包文件WSConsole.war,并将其复制到现有的IBM i集成文件系统(IFS)目录,例如/ home /。
在IBM Web Administration for i GUI上,单击左侧面板上的“ 管理已安装的应用程序 ”,然后单击“ 安装”以启动安装向导。
图3.启动Install New Application向导以安装WebSocket应用程序
按照向导,接受所有默认值,但该应用程序的WAR文件的安装位置除外。 指定实际应用程序的IFS目录和文件。 单击完成以完成应用程序的安装。 该应用程序应在“ 已安装的应用程序”表中列出并自动启动。 WebSocket服务器现在可以测试了。
图4.“管理已安装的应用程序”页面上列出的WebSocket应用程序
第6步。访问网页以验证WebSocket应用程序
要使用从示例列表中下载HTML文件,请打开浏览器并输入URI:http://your.server.name:10000/WSConsole/WSConsole.html
如果一切正常,将显示以下网页。
图5.访问WebSocket客户端网页
输入WebSocket服务器URI, ws://your.server.name:10000 / WSConsole / CLRunner ,然后单击Connect 。 如果没有错误,将显示如图6所示的文本。
图6. Java中的WebSocket服务器
为了实际测试WebSocket连接,我们将输入我们最喜欢的CL命令。 在命令提示符下输入WRKSBS。 显示输出,如图7所示。
图7.通过WebSocket在IBM i上运行CL命令
根据需要输入其他CL命令。 每个命令应快速返回结果,而无需任何其他连接。
实现此应用程序的另一种方法是使用传统的HTTP请求和响应。 在这种方法中,每次用户运行CL命令时,CL命令都会包含在HTTP请求中,结果会包含在HTTP响应中。 为每个请求创建HTTP连接都需要花费额外的时间,并且我们可以看到很多重复的数据,例如在客户端和服务器之间传递的常见HTTP请求和响应标头。 使用WebSocket时,仅必要的数据(在这种情况下为CL命令和结果)通过连接传递。 这样既节省了带宽,又节省了时间,对于实时Web应用程序而言,这一节省至关重要。
HTTP协议仅允许客户端向服务器发送请求,而服务器端无法向客户端初始化请求。 现在,通过使用新的WebSocket技术,服务器可以将请求发送到客户端。 因为WebSocket连接是在客户端和服务器之间建立的全双工单套接字连接,所以可以在客户端和服务器之间的各个方向上发送消息。 例如,如果达到了超时并且在整个会话中不需要再创建新的连接,则服务器端可以主动终止连接并将关闭事件发送给客户端。这样可以节省时间和系统资源。
步骤7.将Integrated Web Application Server实例配置为使用SSL
WebSocket还支持通过SSL进行通信。 在此步骤中,我们将配置集成Web应用程序服务器以使用SSL,然后通过SSL测试WebSocket连接。
点击左侧面板上配置SSL启动配置SSL向导。 在本文中,我们将使用默认设置来创建SSL配置。 单击“ 下一步”指定SSL端口。 在此示例中,选择端口10443 。
图8.为SSL配置指定端口信息
单击下一步以指定SSL密钥库信息。 保留面板上的默认值以创建新的密钥库。
图9.指定密钥库信息
指定新创建的密钥库文件的密码,然后单击下一步 。
图10.指定密钥库的密码
在摘要面板上,单击“ 完成”以完成SSL配置。
点击停止
步骤8.通过SSL验证WebSocket服务器
访问https://your.server.name:10443/WSConsole/WSConsole.html网页以验证该应用程序是否正常运行。 如果一切正常,将再次显示步骤6中提到的页面。 在URI字段中输入wss ://your.server.name:10000 / WSConsole / CLRunner ,然后通过SSL连接到WebSocket服务器。 对于通过HTTP进行的普通WebSocket连接,URI以'ws'开头。 对于通过SSL的WebSocket连接,URI以'wss'开头。
图11.使用SSL连接到WebSocket
在上一节中,我们使用Java创建了WebSocket Web应用程序,然后配置了SSL,然后在IBM i平台上运行了该应用程序。 通过与传统的HTTP请求/响应模型进行比较,我们还展示了使用WebSocket运行示例的一些优势。 在下一节中,我们将向您展示如何通过在IBM i上使用Node.js创建相同的示例。
使用Node.js创建WebSocket服务器
在下一部分中,我们将探索使用在IBM i上本地运行的Node.js创建和访问WebSocket服务器。
步骤1.设置Node.js环境
Node.js包含在5733OPS产品的选项1中。 有关基本的Node.js环境设置和验证,请参阅带有Node.js的文章IBM i上的本机JavaScript应用程序 。 对于此示例,我们将使用完全相同的客户端JavaScript。 用于Node.js的功能更强大的WebSocket插件之一是Socket.IO。 它用于实时应用程序交互。 您可以在http://socket.io/上找到有关Socket.IO附加组件的更多详细信息。
在本节中,我们将使用一个简单的WebSocket插件创建一个项目。 完成这些步骤后,您可以将该项目分发并部署到任何其他Node.js环境。
初始化一个Node.js项目。
- 创建项目目录。
在PASE环境中,创建一个名为wsexample的空目录并进入该目录。
mkdir wsexample cd wsexample
- 初始化项目。
发出以下命令来初始化Node.js项目。
npm init
上面的命令将指导您完成项目的设置以及带有必要信息的package.json文件的创建。
图12.创建和配置一个新的Node.js项目
对于此示例,我们将保留默认选项和创建的package.json文件,如以下清单所示。
清单3.项目配置
{
"name": "wsexample",
"version": "1.0.0",
"description": "my first websocket app",
"main": "index.js",
"author": ""
}
- 安装依赖项。
运行以下命令以将websocket加载项安装为项目的依赖项。
npm install websocket –save
注意 :WebSocket附加安装需要gcc 。 另外,请参阅有关如何在PASE中安装gcc的更多信息。 现在可以通过5733OPS的选项3获得GCC支持。
如果未报告错误,则将使用新的依赖项信息自动更新package.json文件。
"dependencies": {
"websocket": "^1.0.22"
}
现在,已初始化Node.js WebSocket应用程序wsexample,并准备添加该应用程序。
第2步。为Node.js创建一个WebSocket应用程序
此示例使用上一部分中使用的WSConsole.html文件中的相同HTML应用程序,因为WebSocket协议独立于实现。 将WSConsole.html文件复制到服务器上wsexample项目的同一目录中。
Node.js WebSocket服务器的功能与我们之前在Java中展示的示例完全相同。 该示例同时支持通过SSL和非SSL的WebSocket连接。 如果需要使用安全连接,则需要准备私钥和证书文件并将其放入项目目录。
使用以下代码行在wsexample项目目录中创建一个名为index.jsJavaScript文件。 这将创建一个侦听8888端口的HTTP实例和一个侦听8889端口的HTTPS实例。
清单4. JavaScript中的WebSocket服务器实现
var http = require('http');
var https = require('https'); // If need wss support
var fs = require('fs');
var url = require('url');
var WebSocketServer = require('websocket').server;
var xt = require('/QOpenSys/QIBM/ProdData/Node/os400/xstoolkit/lib/itoolkit');
var conn = new xt.iConn("*LOCAL");
// If need wss support
var options = {
key: fs.readFileSync('privateKey.key'),
cert: fs.readFileSync('certificate.crt')
};
function respond(req, res) {
console.log((new Date()) + ' Received request for ' + req.url);
var realPath = __dirname + url.parse(req.url).pathname;
fs.exists(realPath, function(exists){
if(exists){
var file = fs.createReadStream(realPath);
res.writeHead(200, {'Content-Type': 'text/html'});
file.on('data', res.write.bind(res));
file.on('close', res.end.bind(res));
} else {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end("404 Not Found");
}
});
}
var server = http.createServer(respond);
var sserver = https.createServer(options, respond); // If need wss support
var wsServer = new WebSocketServer({
httpServer: [server, sserver], // If need both ws and wss support, use this.
// httpServer: server, // If only need ws support, use this.
autoAcceptConnections: false
});
wsServer.on('request', function(request) {
var path = require('url').parse(request.resource).pathname;
console.log((new Date()) + ' Received request for ' + path + '.');
var connection = request.accept(null, request.origin);
var addr = connection.socket.localAddress;
console.log((new Date()) + ' Peer ' + connection.remoteAddress + " connected.");
connection.sendUTF("[From Server] Connected to " + addr);
connection.on('message', function(message) {
if (/^\/CLRunner\/?$/.test(path) && message.type === 'utf8') {
console.log((new Date()) + ' Received Message: ' + message.utf8Data);
conn.add(xt.iSh("system -i '" + message.utf8Data + "'"));
conn.run(function(result) {
connection.sendUTF("[From Server] " + addr + "\n" + result.slice(50, -18));
});
}
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
server.listen(8888, function() {
console.log((new Date()) + ' HTTP Server is listening on port 8888');
});
// If need wss support
sserver.listen(8889, function() {
console.log((new Date()) + ' HTTPS Server is listening on port 8889');
});
在清单4的代码中,我们使用现有的HTTP / HTTPS对象创建了一个WebSocket服务器。 实际上, WebSocketServer
的构造函数允许绑定到表示为数组参数的多个HTTP对象。 出于安全原因,建议禁用autoAcceptConnections
以拒绝无效请求。
当WebSocket服务器收到连接请求时,事件处理程序wsServer.on('request')
建立连接。 然后,连接处理程序connection.on('message')
读取消息并响应客户端。
通过在项目根目录中调用节点index.js来启动WebSocket服务器。
图13.启动Node.js WebSocket应用程序
步骤3.验证WebSocket服务器
因为我们使用的是相同的测试客户端,所以请确保将WSConsole.html文件复制到项目目录中。 启动您喜欢的浏览器,如果配置了SSL,则输入http://your.server.ip:8888 / WSConsole.html或https://your.server.ip:8889 / WSConsole.html 。 如果没有问题,将显示与Java示例相同的页面。
在第一个文本框中,填写WebSocket服务器地址。 如果您需要SSL /传输层安全性(TLS)连接,则应该类似于ws://your.server.ip:8888 / CLRunner或wss://your.server.ip:8889 / CLRunner 。 然后单击“ 连接” 。
图14.在Node.js中连接到WebSocket服务器

如果没有问题,服务器将以一条消息响应,指示已建立连接。 现在,我们可以在第二个文本框中填写您需要运行的CL命令(例如WRKSBS)。 单击运行发送请求。 您将看到来自服务器的响应,如图15所示。
图15.通过Node.js中的WebSocket运行CL命令
现在,您已经运行了一个简单的WebSocket应用程序( wsexample) ,您可以复制wsexample目录并将其分发到已安装并配置了Node.js正确版本的任何其他系统。
将i的HTTP Server与WebSocket关联
本节介绍如何将HTTP Server for i与我们刚刚创建的WebSocket应用程序相关联,以在IBM i上创建完整的生产Web环境。
图16.通过i上的HTTP Server将WebSocket请求隧道传输到后端WebSocket服务器
步骤1.为i创建一个HTTP Server实例
在将HTTP Server与WebSocket应用程序关联之前,必须存在用于i的HTTP Server实例。 IBM Web Administration for i (http://your.server.name:2001/HTTPAdmin )可以帮助为i实例创建HTTP Server。 有关如何为i创建HTTP Server实例的详细信息,请参阅IBM i知识中心 。
本文以在服务器192.168.0.103上运行的HTTP服务器WebSocket(根目录:/ www / websocket,端口:80,SSL虚拟主机端口:443)作为示例,以演示针对i的HTTP Server与IBM上的WebSocket的配置和关联。一世。
步骤2.为i配置HTTP服务器
为了将HTTP Server for i与WebSocket关联,需要新的Apache 2.4.x mod_proxy_wstunnel模块。 该模块需要mod_proxy服务,并支持将WebSocket连接隧道传输到后端WebSocket服务器。 通过以下HTTP标头将连接自动升级为WebSocket连接。
Upgrade: WebSocket
Connection: Upgrade
创建对WebSocket服务器的代理请求的一种简单方法是使用ProxyPass指令,如以下示例所示。
ProxyPass /ws/ ws://echo.websocket.org/
ProxyPass /wss/ wss://echo.websocket.org/
在以下示例中,我们将HTTP服务器与上一节中创建的Java WebSocket服务器相关联。 然后,在HTTP Server配置(httpd.conf)文件中指定以下指令。
清单5. HTTP Server配置(httpd.conf)文件片段
LoadModule ibm_ssl_module /QSYS.LIB/QHTTPSVR.LIB/QZSRVSSL.SRVPGM
LoadModule proxy_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule proxy_http_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule proxy_connect_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule proxy_ftp_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule proxy_wstunnel_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
ProxyPass /ws ws://192.168.0.101:10000/WSConsole/CLRunner
<VirtualHost *:443>
SSLEngine On
SSLAppName IBM_SSL_TEST
SSLProtocolDisable SSLv2 SSLv3
SSLProxyEngine on
SSLProxyAppName IBM_SSL_TEST
SSLProxyProtocolDisable SSLv2 SSLv3
SSLProxyVerify 1
ProxyPass /wss wss://192.168.0.101:10443/WSConsole/CLRunner
</VirtualHost>
注意事项 :
- 要获得SSL支持,请创建应用程序ID IBM_SSL_TEST,并使用WebAdmin GUI HTTP SSL向导或数字证书管理器(DCM)工具为其分配有效的证书。
- 为了使测试客户端界面能够正常工作,请将相同的WSConsole.html文件放在HTTP Server文档根目录中,并确保默认的HTTP Server用户配置文件QTMHHTTP具有* RX权限。
- 将192.168.0.101替换为运行Java WebSocket的服务器IP地址或主机名。
步骤3.验证i的WebSocket服务器和HTTP Server之间的关联
使用CL命令STRTCPSVR SERVER(* HTTP)HTTPSVR(websocket)或使用Web Admin GUI为i启动HTTP Server。 打开Web浏览器并输入URL:http://192.168.0.103/WSConsole.html。
将显示测试界面。 在“ URI”字段中输入ws://192.168.0.103/ws ,然后单击“ 连接”以连接到WebSocket服务器。 如果显示服务器已成功连接,请在命令字段中输入CL命令WRKSYSSTS并单击运行 。 如下图所示显示CL命令的输出。
图17.连接到HTTP Server提供的WebSocket URI
为了建立WebSocket连接,客户端发送一个WebSocket握手请求,服务器为此返回一个WebSocket握手响应。 在此示例中,我们捕获了以下HTTP请求和响应标头。
清单6. HTTP请求
GET http://192.168.0.103/ws HTTP/1.1
Origin: http://192.168.0.103
Connection: Upgrade
Upgrade: Websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: GqQOT2I5N+f9lp+daNccwQ==
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: 192.168.0.103
清单7. HTTP响应
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 2M7J7SdJKynSSUCMPPVifgYKZ7E=
Origin: http://192.168.0.103
图18.连接到HTTP Server提供的WebSocket SSL URI
您可以修改ProxyPass
指令以将Node.js WebSocket服务器用作后端服务器,并进行相同的测试。
在上一节中,我们演示了通过使用新的proxy_wstunnel
模块并以非SSL和SSL方式访问它,将IBM i HTTP Server与基于Java的WebSocket应用程序关联的最简单方法。 下一节将向您展示使用WebSocket和HTTP Server进行负载平衡的更复杂的方案。
使用WebSocket和HTTP Server进行负载平衡
上一节演示了如何使用ProxyPass
指令连接到WebSocket服务器。 此外,它还可以使我们将HTTP Server中的WebSocket用作负载平衡服务器。 下一节将向您展示如何做到这一点。
图19.通过HTTP Server作为负载平衡器连接到WebSocket服务器
删除或注释掉以前的ProxyPass
指令,将proxy_balancer
和byrequests
负载平衡方法模块添加到httpd.conf文件中(请注意以粗体显示的行)。
清单8. HTTP Server配置(httpd.conf)文件片段
LoadModule ibm_ssl_module /QSYS.LIB/QHTTPSVR.LIB/QZSRVSSL.SRVPGM
LoadModule proxy_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule proxy_http_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule proxy_connect_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule proxy_ftp_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule proxy_balancer_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule proxy_wstunnel_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
LoadModule lbmethod_byrequests_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
BalancerInherit Off
ProxyPassInherit Off
ProxyPass /ws balancer://mycluster/CLRunner
ProxyPassReverse /ws balancer://mycluster/CLRunner
<Proxy balancer://mycluster/CLRunner>
BalancerMember ws://192.168.0.101:10000/WSConsole
BalancerMember ws://192.168.0.102:8888
</Proxy>
<VirtualHost *:443>
SSLEngine On
SSLAppName IBM_SSL_TEST
SSLProtocolDisable SSLv2 SSLv3
SSLProxyEngine on
SSLProxyAppName IBM_SSL_TEST
SSLProxyProtocolDisable SSLv2 SSLv3
SSLProxyVerify 1
ProxyPass /wss balancer://mycluster/CLRunner
ProxyPassReverse /wss balancer://mycluster/CLRunner
<Proxy balancer://mycluster/CLRunner>
BalancerMember wss://192.168.0.101:10443/WSConsole
BalancerMember wss://192.168.0.102:8889
</Proxy>
</VirtualHost>
在示例中,我们使用默认的byrequests
负载平衡方法。 您还可以选择bybusyness
或bytraffic
负载平衡方法。
注意 :如果您选择使用bybusyness
或bytraffic
负载均衡方法,则还必须对httpd.conf文件进行以下更改。 在此示例中,我们使用bytraffic
。
- 加载
bytraffic
模块。
LoadModule lbmethod_bytraffic_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM
- 设置
lbmethod
平衡器参数。
<Proxy balancer://mycluster/CLRunner>
BalancerMember wss://192.168.0.101:10443/WSConsole
BalancerMember wss://192.168.0.102:8889
ProxySet lbmethod=bytraffic
</Proxy>
执行与上一节相同的测试。 然后,您将发现HTTP Server第一次连接到Node.js WebSocket服务器以运行CL命令。 单击断开连接或打开新的浏览器以再次连接。 第二次,HTTP服务器连接到Java WebSocket服务器以运行CL命令。 第三次,它连接到Node.js WebSocket服务器,第四次,它连接到Java Websocket服务器,依此类推。 创建新连接时,后端Node.js和Java WebSocket服务器轮流由HTTP Server连接,这就是byrequest
负载平衡方法的工作方式。
图20.连接到WebSocket服务器并验证负载平衡
摘要
WebSocket已成为Web通信领域中非常热门的技术,越来越多的客户愿意使用它在IBM i平台上运行自己的Web解决方案。 在您的Web环境的最前端使用HTTP Server for i是您的Web解决方案的明智方法。 将它们捆绑在一起以充分利用这些优势在IBM i上提供新的Web解决方案非常有用。