- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我已经在 stackoverflow 中进行了 google 和搜索,任何与 socket.io+tls、node.js+tls 或 ssl 等相关的线程……但我找不到任何构建我需要的方法:
一个node.js服务器通过socket.io连接到客户端并使用tls(只需要服务器认证)
到目前为止,我已经在不使用 tls 的情况下连接了服务器和客户端。
当我创建我的 node.js 服务器(监听端口 3000)并使用 tls 时,我可以使用命令:
openssl s_client -connect localhost:3000
一切似乎都没问题,但我尝试连接我的 socket.io 客户端时,我总是遇到错误。
这是我的简单服务器代码:
var tls = require('tls');
var fs = require('fs');
var options = {
key: fs.readFileSync('evServer-key.pem'),
cert: fs.readFileSync('evServer-cert.pem'),
requestCert: false,
};
var server = tls.createServer(options, function(cleartextStream) {
console.log('server connected',
cleartextStream.authorized ? 'authorized' : 'unauthorized');
cleartextStream.write("welcome!\n");
cleartextStream.setEncoding('utf8');
cleartextStream.pipe(cleartextStream);
});
io = require('socket.io').listen(server);
server.listen(3000, function() {
console.log('server bound');
});
io.sockets.on('connection', function (socket) {
// When new users join
socket.on('join', function (data, fn) {
console.log("User connected");
socket.set('socketname', 'name', function () {
socket.emit('Connection received') ; // for the current socket
});
});
// --------------- client events
socket.on('clientjoin', function (data) {
client_socket = socket;
console.log("BT Client joined");
});
socket.on('hello', function (data) {
client_socket = socket;
console.log("Hello received");
socket.emit('Hi there!');
});
// When a client disconnects
socket.on('disconnect', function () {
socket.get('nickname', function (err, nickname) {
console.log(nickname + " logged out")
});
});
});
这是客户端中的连接:
socket = new SocketIO("http://"+this.serverIpAddress+":3000/");
如果我使用:
http://localhost:3000
我收到连接拒绝错误:
02-22 15:37:41.702: W/System.err(621): io.socket.SocketIOException: Error while handshaking
02-22 15:37:41.702: W/System.err(621): at io.socket.IOConnection.handshake(IOConnection.java:322)
02-22 15:37:41.702: W/System.err(621): at io.socket.IOConnection.access$600(IOConnection.java:39)
02-22 15:37:41.702: W/System.err(621): at io.socket.IOConnection$ConnectThread.run(IOConnection.java:199)
02-22 15:37:41.702: W/System.err(621): Caused by: java.net.ConnectException: localhost/127.0.0.1:3000 - Connection refused
02-22 15:37:41.702: W/System.err(621): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:207)
02-22 15:37:41.712: W/System.err(621): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:437)
02-22 15:37:41.712: W/System.err(621): at java.net.Socket.connect(Socket.java:983)
02-22 15:37:41.712: W/System.err(621): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>(HttpConnection.java:75)
02-22 15:37:41.712: W/System.err(621): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>(HttpConnection.java:48)
02-22 15:37:41.712: W/System.err(621): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection$Address.connect(HttpConnection.java:322)
02-22 15:37:41.712: W/System.err(621): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionPool.get(HttpConnectionPool.java:89)
02-22 15:37:41.712: W/System.err(621): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getHttpConnection(HttpURLConnectionImpl.java:285)
02-22 15:37:41.712: W/System.err(621): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.makeConnection(HttpURLConnectionImpl.java:267)
02-22 15:37:41.712: W/System.err(621): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.retrieveResponse(HttpURLConnectionImpl.java:1018)
02-22 15:37:41.712: W/System.err(621): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:512)
02-22 15:37:41.742: W/System.err(621): at io.socket.IOConnection.handshake(IOConnection.java:313)
02-22 15:37:41.742: W/System.err(621): ... 2 more
02-22 15:37:41.742: I/io.socket(621): Cleanup
02-22 15:55:57.352: I/dalvikvm(621): Jit: resizing JitTable from 512 to 1024
02-22 16:00:54.763: I/AsyncTask(621): onPreExecute
02-22 16:00:54.772: I/ClientActivity(621): C: Connecting...
02-22 16:00:54.782: I/AsyncTask(621): onPostExecute: Completed.
02-22 16:00:54.792: I/AsyncTask(621): an Error occured
02-22 16:00:54.792: W/System.err(621): io.socket.SocketIOException: Error while handshaking
.
.
.
如果我使用
https://localhost:3000
我得到了另一个空指针错误:
02-22 16:06:06.432: I/AsyncTask(666): onPreExecute
02-22 16:06:06.442: I/ClientActivity(666): C: Connecting...
02-22 16:06:06.503: I/AsyncTask(666): onPostExecute: Completed.
02-22 16:06:06.512: I/AsyncTask(666): an Error occured
02-22 16:06:06.512: W/System.err(666): io.socket.SocketIOException: Error while handshaking
02-22 16:06:06.512: W/System.err(666): at io.socket.IOConnection.handshake(IOConnection.java:322)
02-22 16:06:06.512: W/System.err(666): at io.socket.IOConnection.access$600(IOConnection.java:39)
02-22 16:06:06.512: W/System.err(666): at io.socket.IOConnection$ConnectThread.run(IOConnection.java:199)
02-22 16:06:06.523: W/System.err(666): Caused by: java.lang.NullPointerException
02-22 16:06:06.523: W/System.err(666): at io.socket.IOConnection.handshake(IOConnection.java:301)
02-22 16:06:06.523: W/System.err(666): ... 2 more
我也试过写我的外部 IP 地址而不是 localhost 或 127.0.0.1 但它仍然不起作用,这是我想做的不可能吗?有什么想法或建议吗?
提前谢谢你。
更新:
我一直在努力,但我还没有实现连接客户端和服务器。我在客户端 (android) 尝试过的,因为我正在使用 Gottox 的 socket.io 库,我无法使用 user568109 提出的解决方案,将其添加到我的客户端代码中:
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(new FileInputStream("/sdcard/cacert.crt"));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
SocketIO.setDefaultSSLSocketFactory(SSLContext.getInstance("SSL"));
socket = new SocketIO("https://"+this.serverIpAddress+":3000/");
其中,cacert.crt 是我创建的证书颁发机构的证书,我用它来签署服务器的 key 。
我可以毫无问题地通过 https 将 Web 浏览器连接到我的服务器,但是我的 android 应用程序抛出以下错误:
02-26 16:39:18.420: I/AsyncTask(27913): onPreExecute
02-26 16:39:18.420: I/ClientActivity(27913): C: Connecting...
02-26 16:39:18.445: E/ClientActivity(27913): C: Error
02-26 16:39:18.445: E/ClientActivity(27913): java.security.cert.CertificateException: org.apache.harmony.security.asn1.ASN1Exception: ASN.1 sequence identifier expected at [0], got 43
02-26 16:39:18.445: E/ClientActivity(27913): at org.apache.harmony.security.provider.cert.X509CertImpl.<init>(X509CertImpl.java:106)
02-26 16:39:18.445: E/ClientActivity(27913): at org.apache.harmony.security.provider.cert.X509CertFactoryImpl.getCertificate(X509CertFactoryImpl.java:656)
02-26 16:39:18.445: E/ClientActivity(27913): at org.apache.harmony.security.provider.cert.X509CertFactoryImpl.engineGenerateCertificate(X509CertFactoryImpl.java:109)
02-26 16:39:18.445: E/ClientActivity(27913): at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:195)
02-26 16:39:18.445: E/ClientActivity(27913): at com.android.locaalton.CommTask.doInBackground(CommTask.java:61)
02-26 16:39:18.445: E/ClientActivity(27913): at com.android.locaalton.CommTask.doInBackground(CommTask.java:1)
02-26 16:39:18.445: E/ClientActivity(27913): at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-26 16:39:18.445: E/ClientActivity(27913): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-26 16:39:18.445: E/ClientActivity(27913): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-26 16:39:18.445: E/ClientActivity(27913): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-26 16:39:18.445: E/ClientActivity(27913): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-26 16:39:18.445: E/ClientActivity(27913): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-26 16:39:18.445: E/ClientActivity(27913): at java.lang.Thread.run(Thread.java:856)
02-26 16:39:18.445: E/ClientActivity(27913): Caused by: org.apache.harmony.security.asn1.ASN1Exception: ASN.1 sequence identifier expected at [0], got 43
02-26 16:39:18.445: E/ClientActivity(27913): at org.apache.harmony.security.asn1.BerInputStream.expected(BerInputStream.java:464)
02-26 16:39:18.445: E/ClientActivity(27913): at org.apache.harmony.security.asn1.BerInputStream.readSequence(BerInputStream.java:502)
02-26 16:39:18.445: E/ClientActivity(27913): at org.apache.harmony.security.asn1.DerInputStream.readSequence(DerInputStream.java:105)
02-26 16:39:18.445: E/ClientActivity(27913): at org.apache.harmony.security.asn1.ASN1Sequence.decode(ASN1Sequence.java:40)
02-26 16:39:18.445: E/ClientActivity(27913): at org.apache.harmony.security.asn1.ASN1Type.decode(ASN1Type.java:91)
02-26 16:39:18.445: E/ClientActivity(27913): at org.apache.harmony.security.provider.cert.X509CertImpl.<init>(X509CertImpl.java:101)
02-26 16:39:18.445: E/ClientActivity(27913): ... 12 more
对这个新问题有什么想法吗?
最佳答案
Web 套接字可以是未加密的 ws://或加密的 wss://(ws+ssl)。 Socket.io 允许使用安全选项在两者之间进行选择,如下所示:
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
socket = io.connect('http://localhost:3000', {secure:true}); //encrypted
socket = io.connect('http://localhost:3000', {secure:false}); //unencrypted
这应该满足您所有的 websocket 加密要求。无论您遇到什么错误,都是因为您试图将 tls 服务器用作 http/https 服务器。openssl s_client -connect localhost:3000
是访问它的正确方法。 http://localhost:3000
将要求在该地址运行 http 服务器,但您的服务器是 tls ( http://nodejs.org/api/tls.html#tls_tls_ssl)。
您应该将其用作 https 服务器。它是 tls.Server 的子类,并发出与 http.Server 相同的事件。 http://nodejs.org/api/https.html#https_class_https_server
var https = require('https'); //tls changed to https
var server = https.createServer(options, function(cleartextStream) {
console.log('server connected',
您的服务器现在是 https 并且您的 https://localhost:3000
应该可以工作。尝试使用 openssl s_client
连接到它以检查它是否正常工作。
评论后更新
user1249517 你应该在提问时说明错误的来源。你在 node.js、ssl 和 socket.io 下标记了它,但它应该是 java、android 和 socket。 socket.io 是 javascript 库,而您使用的是 socket.io 的 gottox java 库。
无论如何,当您使用浏览器查看站点时,证书由浏览器本身管理,当您使用 java 应用程序时,它应该处理证书。您遇到的错误:
Caused by: org.apache.harmony.security.asn1.ASN1Exception: ASN.1 sequence identifier expected at [0], got 43
ASN.1 是 X.509 证书的编码格式。 ASN.1 sequence identifier expected
表示您的证书已损坏/无效的 ASN.1 格式。您不应直接使用您的证书,而应使用 openssl
将其转换为 ASN.1 格式。 .尝试这样的事情。
openssl asn1parse -in mycert.pem
指定证书的输入格式,并在解析前进行验证。如果所有证书都有效,则代码中存在一些错误。
关于node.js - 无法使用 tls 连接 node.js 中的 socket.io,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15026330/
IO 设备如何知道属于它的内存中的值在memory mapped IO 中发生了变化? ? 例如,假设内存地址 0 专用于保存 VGA 设备的背景颜色。当我们更改 memory[0] 中的值时,VGA
我目前正在开发一个使用Facebook sdk登录(通过FBLoginView)的iOS应用。 一切正常,除了那些拥有较旧版本的facebook的人。 当他们按下“使用Facebook登录”按钮时,他
假设我有: this - is an - example - with some - dashesNSRange将使用`rangeOfString:@“-”拾取“-”的第一个实例,但是如果我只想要最后
Card.io SDK提供以下详细信息: 卡号,有效期,月份,年份,CVV和邮政编码。 如何从此SDK获取国家名称。 - (void)userDidProvideCreditCardInfo:(Car
iOS 应用程序如何从网络服务下载图片并在安装过程中将它们安装到用户的 iOS 设备上?可能吗? 最佳答案 您无法控制应用在用户设备上的安装,因此无法在安装过程中下载其他数据。 只需在安装后首次启动应
我曾经开发过一款企业版 iOS 产品,我们公司曾将其出售给大型企业,供他们的员工使用。 该应用程序通过 AppStore 提供,企业用户获得了公司特定的配置文件(包含应用程序配置文件)以启用他们有权使
我正在尝试将 Card.io SDK 集成到我的 iOS 应用程序中。我想为 CardIO ui 做一个简单的本地化,如更改取消按钮标题或“在此保留信用卡”提示文本。 我在 github 上找到了这个
我正在使用 CardIOView 和 CardIOViewDelegate 类,没有可以设置为 YES 的 BOOL 来扫描 collectCardholderName。我可以看到它在 CardIOP
我有一个集成了通话工具包的 voip 应用程序。每次我从我的 voip 应用程序调用时,都会在 native 电话应用程序中创建一个新的最近通话记录。我在 voip 应用程序中也有自定义联系人(电话应
iOS 应用程序如何知道应用程序打开时屏幕上是否已经有键盘?应用程序运行后,它可以接收键盘显示/隐藏通知。但是,如果应用程序在分屏模式下作为辅助应用程序打开,而主应用程序已经显示键盘,则辅助应用程序不
我在模拟器中收到以下错误: ImageIO: CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedIm
如 Apple 文档所示,可以通过 EAAccessory Framework 与经过认证的配件(由 Apple 认证)进行通信。但是我有点困惑,因为一些帖子告诉我它也可以通过 CoreBluetoo
尽管现在的调试器已经很不错了,但有时找出应用程序中正在发生的事情的最好方法仍然是古老的 NSLog。当您连接到计算机时,这样做很容易; Xcode 会帮助弹出日志查看器面板,然后就可以了。当您不在办公
在我的 iOS 应用程序中,我定义了一些兴趣点。其中一些有一个 Kontakt.io 信标的名称,它绑定(bind)到一个特定的 PoI(我的意思是通常贴在信标标签上的名称)。现在我想在附近发现信标,
我正在为警报提示创建一个 trigger.io 插件。尝试从警报提示返回数据。这是我的代码: // Prompt + (void)show_prompt:(ForgeTask*)task{
您好,我是 Apple iOS 的新手。我阅读并搜索了很多关于推送通知的文章,但我没有发现任何关于 APNS 从 io4 到 ios 6 的新更新的信息。任何人都可以向我提供 APNS 如何在 ios
UITabBar 的高度似乎在 iOS 7 和 8/9/10/11 之间发生了变化。我发布这个问题是为了让其他人轻松找到答案。 那么:在 iPhone 和 iPad 上的 iOS 8/9/10/11
我想我可以针对不同的 iOS 版本使用不同的 Storyboard。 由于 UI 的差异,我将创建下一个 Storyboard: Main_iPhone.storyboard Main_iPad.st
我正在写一些东西,我将使用设备的 iTunes 库中的一部分音轨来覆盖 2 个视频的组合,例如: AVMutableComposition* mixComposition = [[AVMutableC
我创建了一个简单的 iOS 程序,可以顺利编译并在 iPad 模拟器上运行良好。当我告诉 XCode 4 使用我连接的 iPad 设备时,无法编译相同的程序。问题似乎是当我尝试使用附加的 iPad 时
我是一名优秀的程序员,十分优秀!