使用 NodeJS 添加的自签名证书 (HTTPS) 简单地将文本形式的 NodeJS Socket io 传递给 android 客户端,我收到错误
添加:android:usesCleartextTraffic="true",互联网权限
错误:I/IO 连接错误:com.github.nkzawa.engineio.client.EngineIOException:xhr 轮询错误
我试过Android: socket.io io.socket.engineio.client.EngineIOException: XHR poll error
在那个答案中 io.set('transsports', ['websocket']);想在 nodejs 服务器中添加但是,我在我的服务器中添加了错误
Error: TypeError: Cannot read property 'transports' of undefined
帮我解决这个问题
App.js
const express = require('express')
const https = require('https')
const fs = require('fs')
const path = require('path')
const app = express()
var bodyParser = require('body-parser');
var io = require('socket.io')(https);
io.on('connection',function(socket){
console.log('one user connected '+socket.id);
socket.emit('CHAT',{"message":"hy"});
socket.on('disconnect',function(){
console.log('one user disconnected '+socket.id);
});
})
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
con.connect(function(err) {
if (err) throw err
console.log('You are now connected with mysql database...')
});
app.use('/',(req,res,next) => {
res.send('Hello from SSL server!!!')
})
const sslServer = https.createServer(
{
key: fs.readFileSync(path.join(__dirname,'cert','key.pem')),
cert: fs.readFileSync(path.join(__dirname,'cert','cert.pem')),
},
app
)
sslServer.listen(3000, () => console.log("Secure Server on port 3000"))
MainActivity.java
public class Main2Activity extends AppCompatActivity {
public Button button1;
public TextView text1,text2,text3,text4;
public EditText edit1;
public String message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
button1 = findViewById(R.id.button);
text1 = findViewById(R.id.textview);
edit1 = findViewById(R.id.edit);
// mSocket.connect();
text1.setText("");
final String uri = "https://192.168.43.182:3000";
try {
// Load CAs from an InputStream.
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Certificate certificate = certificateFactory.generateCertificate(
getResources().openRawResource(R.raw.cert)); // from file server.crt
// Create a KeyStore containing the trusted CAs.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", certificate);
// Create a TrustManager that trusts the CAs in KeyStore.
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
// Create an SSLContext that uses the TrustManager.
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
Log.i("uri", "sslContext created");
IO.setDefaultSSLContext(sslContext);
IO.Options options = new IO.Options();
options.secure = true;
options.path = "/web-live";
options.reconnection = true;
options.upgrade = true;
options.sslContext = sslContext;
URL url = new URL(uri);
final HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
httpsURLConnection.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
Log.i("HostnameVerifier", "Approving certificate for " + hostname);
return true; // Do nothing.
}
});
new Thread(new Runnable() {
@Override
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
httpsURLConnection.getInputStream()));
Log.i("httpsURLConnection", "url connected");
String line; //FIXME: readLine kicks in socket.io at least on gingerbread!?
while((line = in.readLine()) != null) {
Log.i("httpsURLConnection", line);
}
in.close();
} catch (IOException e) {
}
}
}).start();
Socket socket = IO.socket(uri, options);
socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
@Override
public void call(Object... args) {
for(Object o : args) {
Log.i("IO " + Socket.EVENT_CONNECT_ERROR, o.toString());
}
}
}).on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.i("IO", Socket.EVENT_CONNECT_TIMEOUT);
}
}).on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.i("IO", Socket.EVENT_CONNECT);
}
}).on("secure_data", new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.i("IO secure_data", args[0].toString());
}
});
socket.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
密钥由 openssl 生成,在使用 RestApi 时它工作正常。我只有连接问题帮我解决这个问题
答案 0 :(得分:0)
尝试检查以下可能在客户端和服务器之间
请检查下面的代码行可能对您有帮助
public void initSocket() {
try {
SSLContext mySSLContext = SSLContext.getInstance("TLS");
mySSLContext.init(null, trustAllCerts, new SecureRandom());
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.hostnameVerifier(myHostnameVerifier)
.sslSocketFactory(mySSLContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0])
.build();
IO.setDefaultOkHttpWebSocketFactory(okHttpClient);
IO.setDefaultOkHttpCallFactory(okHttpClient);
IO.Options opts = new IO.Options();
opts.callFactory = okHttpClient;
opts.webSocketFactory = okHttpClient;
opts.timeout = 60 * 1000;
opts.forceNew = false;
opts.secure = true;
opts.reconnection = true;
mSocket = IO.socket(socketUrl, opts);
mSocket.connect();
mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.e(TAG,"socket connected");
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.e(TAG,"socket disconnected");
}
}).on(Socket.EVENT_ERROR, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.e(TAG,"socket error");
}
}).on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Log.e(TAG,"socket connection timeout");
}
});
} catch (URISyntaxException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
}};
HostnameVerifier myHostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};