我正在尝试通过利用AWS的websocket api网关在我的网站上实现用户之间的消息传递。我看到的每个指南/文档都说要使用wscat测试到网关的连接。我现在可以连接到api网关并使用wscat在客户机之间发送消息,但我正努力通过ts代码使它以编程方式工作。
我想做的是在用户登录后对websocket api网关进行api调用,这样他们就可以在任何时候发送消息。我的后端使用无服务器,前端使用Angular 6。我了解到,我需要向https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
发出post
请求,以便通过websocket连接发送消息,但在我创建的用于连接/获取连接ID的服务中使用typescript时遇到了问题。
在用户成功登录以打开到websocket API网关的连接之后,我正在进行第二次API调用。我尝试调用一个函数,该函数将一个没有正文的post请求(不确定我将在请求正文中发送什么,因为我只是使用wscat工具连接到它)发送到部署无服务器代码后获得的URL。在手动部署API网关之后,我还尝试向AWS控制台中看到的https://URL发出POST请求。
base.service.ts
protected getBaseSocketEndpoint(): string {
// 'wss://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev' <-- tried this too
return 'https://xxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/@connections';
}
Authentication.Service.ts
this.authService.login(username, password).pipe(first()).subscribe(
(response) => {
console.log(response);
this.authService.setCookie('userId', response.idToken.payload.sub);
this.authService.setCookie('jwtToken', response.idToken.jwtToken);
this.authService.setCookie('userEmail', response.idToken.payload.email);
this.authService.setCookie('refreshToken', response.refreshToken.token);
this.toastr.success('Login successful. Redirecting to your dashboard.', 'Success!', {
timeOut: 1500
});
this.authService.connectToWebSocket(response.idToken.payload.sub).pipe(first()).subscribe(
response => {
console.log(response);
}
);
this.routerService.routeToUserDashboard();
},
(error) => {
// const errorMessage = JSON.parse(error._body).message;
this.toastr.error("Incorrect username and password combination.", 'Error!', {
timeOut: 1500
});
}
);
authentication.service.ts扩展基本服务
public connectToWebSocket(userId: string): Observable<any> {
const body = {
userId: userId
};
console.log('calling connectToWebSocket()..');
return this.http.post(this.getBaseSocketEndpoint(), body).pipe(map(response => {
console.log(response);
}));
}
无服务器.yaml
functions:
connectionHandler:
handler: connectionHandler.connectionHandler
events:
- websocket:
route: $connect
cors: true
- websocket:
route: $disconnect
cors: true
defaultHandler:
handler: connectionHandler.defaultHandler
events:
- websocket:
route: $default
cors: true
sendMessageHandler:
handler: messageHandler.sendMessageHandler
events:
- websocket:
route: sendMessage
cors: true
ConnectionHandler.js(lambda)
const success = {
statusCode: 200,
headers: { "Access-Control-Allow-Origin": "*" },
body: "everything is alright"
};
module.exports.connectionHandler = (event, context, callback) => {
var connectionId = event.requestContext.connectionId;
if (event.requestContext.eventType === "CONNECT") {
addConnection(
connectionId,
"b72656eb-db8e-4f32-a6b5-bde4943109ef",
callback
)
.then(() => {
console.log("Connected!");
callback(null, success);
})
.catch(err => {
callback(null, JSON.stringify(err));
});
} else if (event.requestContext.eventType === "DISCONNECT") {
deleteConnection(
connectionId,
"b72656eb-db8e-4f32-a6b5-bde4943109ef",
callback
)
.then(() => {
console.log("Disconnected!");
callback(null, success);
})
.catch(err => {
callback(null, {
statusCode: 500,
body: "Failed to connect: " + JSON.stringify(err)
});
});
}
};
// THIS ONE DOESNT DO ANYHTING
module.exports.defaultHandler = (event, context, callback) => {
callback(null, {
statusCode: 200,
body: "default handler was called."
});
};
const addConnection = (connectionId, userId, callback) => {
const params = {
TableName: CHATCONNECTION_TABLE,
Item: {
connectionId: connectionId,
userId: userId
}
};
var response;
return dynamo
.put(params, function(err, data) {
if (err) {
errorHandler.respond(err, callback);
return;
} else {
response = {
statusCode: 200,
headers: { "Access-Control-Allow-Origin": "*" },
body: JSON.stringify(data)
};
callback(null, response);
}
})
.promise();
};
const deleteConnection = (connectionId, userId, callback) => {
const params = {
TableName: CHATCONNECTION_TABLE,
Key: {
connectionId: connectionId,
userId: userId
}
};
var response;
return dynamo
.delete(params, function(err, data) {
if (err) {
errorHandler.respond(err, callback);
return;
} else {
response = {
statusCode: 200,
headers: { "Access-Control-Allow-Origin": "*" },
body: JSON.stringify(data)
};
callback(null, response);
}
})
.promise();
};
预期:触发POST api调用并打开与Websocket api网关的持久连接。
实际情况:无法通过上面的API调用连接。我在控制台中得到一个403,其中有消息:
CORS策略已阻止从源“http://localhost:4200”访问“https://xxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/@connections”得XMLHttpRequest:对预飞行请求得响应未通过访问控制检查:请求得资源上没有“access-control-allog-origin”标头.
不确定为什么我在我的无服务器文件中启用了CORS时会出现CORS错误。
我也有类似的问题。您可以使用所有的socket.io-client goodness。但必须将“传输”选项设置为:
let socket = io(url, {
reconnectionDelayMax: 1000,
transports: ["websocket"],
});
默认值为
transports: ["polling", "websocket"],
所以您的应用程序将启动轮询并导致CORS错误。文档中并不清楚,但这里有一个有用的链接。
请参阅“基础工程.io客户机的可用选项:”下。
以同样的方式,我想为OTG做这件事。
我实际上是在编程一些东西,不让用户访问Android原生wifi连接页面,所以我在我的Android应用程序中编程。它扫描可用的无线网络,将其显示在列表视图中,然后单击要连接的网络。 事实上,除了我的连接功能之外,一切都很好,这使得我的应用程序崩溃,所以如果你有任何想法...下面是代码(这是用户输入网络通行证后调用的函数)和堆栈跟踪: 堆栈跟踪:
问题内容: 我必须将文件上传到服务器,该服务器仅使用文件上传按钮(通过http)公开jsf网页。我必须自动执行一个过程(作为Java独立过程完成),该过程生成一个文件并将该文件上传到服务器。可悲的是,必须将文件上传到的服务器不提供FTP或SFTP。有没有办法做到这一点? 谢谢,里奇 问题答案: 以编程方式提交JSF生成的表单时,需要确保考虑以下三点: 维护HTTP会话(肯定是网站是否启用了JSF服
目的尝试连接或切换到特定的WiFi网络,无需任何人为干预(用户名和密码除外)。 代码片段 主要活动。kt 类主活动:AppCompat活动(){ } AndroidManifest。xml权限 使用此代码,设备能够连接到WiFi网络,但需要手动关闭和打开WiFi。必须有更好的方法来连接或切换到特定的WiFi网络,而无需任何手动操作。 当前流程: 运行应用程序并单击主屏幕上的按钮连接到WiFi。 转
我正在用jsPlumb构建一个UI,因为我有多个可以连接在一起的盒子。每个框有1个目标和3个源,使用对同一个框DOM元素调用的和方法生成。 每个源通过将其连接到方框不同部分的过滤器属性进行区分: 只能在一个盒子的源和另一个盒子的目标之间进行连接。目标锚点是连续的。 这种安排非常适合我需要的东西,只要处理盒子和拖放连接。 当我想从JSON对象重新创建保存的UI时,问题就出现了。我可以毫无问题地重新创
我的要求是,我使用jsplumb.addEndPoint为两个名为“container0”和“container1”的容器添加两个endpoint。 现在我需要通过编程方式使用连接器链接两个endpoint,但是jsplump.connect创建了一个新endpoint并进行连接,而不是使用我使用jsplump.addEndpoint创建的endpoint。 我如何连接这两个endpoint?此外