您好,我正在React中开发一个web应用程序,它使用Nginx从Express服务器接收SSE数据。
JS服务器
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const crypto = require('crypto');
const app = express();
var lastClientRes = null;
function eventsHandler(req, res, next) {
const headers = {
'Content-Type': 'text/event-stream',
'Connection': 'keep-alive',
'Cache-Control': 'no-cache'
};
res.writeHead(200, headers);
const clientId = Date.now();
const newClient = {
id: clientId,
nonce: null,
cart: null,
res
};
requests.push(newClient);
const data = `data: ${JSON.stringify({client: clientId})}\n\n`;
res.write(data);
req.on('close', () => {
console.log(`${clientId} Connection closed`);
clients = clients.filter(c => c.id !== clientId);
});
}
function sendEventsToAll(newNest) {
clients.forEach(c => c.res.write(`data: ${JSON.stringify(newNest)}\n\n`))
}
async function addCart(req, res) {
const newCart = req.body;
requests.forEach(r => {
if(newCart.client == r.id){
var nonce = crypto.randomBytes(16).toString('base64');
r.nonce = nonce;
r.cart = newCart.cart;
r.res.write(`data: ${JSON.stringify({nonce: nonce})}\n\n`);
}
})
}
async function addCart(req, res) {
const newCart = req.body;
requests.forEach(r => {
if(newCart.client == r.id){
var nonce = crypto.randomBytes(16).toString('base64');
r.nonce = nonce;
r.cart = newCart.cart;
r.res.write(`data: ${JSON.stringify({nonce: nonce})}\n\n`);
}
})
}
async function confirmCart(req, res){
var nonce = req.body.nonce;
var found = -1;
requests.forEach((item, i) => {
if(item.nonce == nonce){
found = i;
return;
}
});
if(found)
{
console.log("OK");
requests[found].res.write(`data: ${JSON.stringify({confirm: true})}\n\n`);
}
}
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.post('/addCart', addCart);
app.post('/confirmCart', confirmCart);
app.get('/events', eventsHandler);
app.get('/status', (req, res) => res.json({clients: clients.length}));
const PORT = 3001;
let requests= [];
let clients = [];
let nests = [];
app.listen(PORT, () => console.log(`SSE service listening on port ${PORT}`));
索引:JS
import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
jsonCart: "",
cartNonce: "",
clientId: "",
cartConfirmed: false,
cart: Array(),
timerId: null,
listening: false,
cartConfermato: ""
};
}
buy(){
if (!this.state.listening) {
const events = new EventSource('https://api.myDomain.com/events', );
events.onmessage = (event) => {
const parsedData = JSON.parse(event.data);
console.log(event.data);
if(parsedData.client != null)
{
this.setState({
clientId: parsedData.client,
});
this.sendCart();
}
if(parsedData.nonce != null)
this.setState({
cartNonce: parsedData.nonce,
});
if(parsedData.confirm == true)
this.setState({
cartNonce: "",
cartConfermato: "Il carrello è stato confermato!"
});
};
this.setState({
listening: true
});
}
}
sendCart(){
var cart = JSON.stringify(this.state.cart.slice());
this.setState({
jsonCart: cart
});
axios.post(`https://api.myDomain.com/addCart`, {client: this.state.clientId, cart: cart});
}
*** ... ***
const events=新事件源('https://api.myDomain.com/events', );
axios。post(<代码>https://api.myDomain.com/addCart,{客户端:this.state.clientId,购物车:cart});
在http中,一切都能正常工作,但如果我使用certbot设置https生成证书,我将不再从express服务器接收“事件”。
chrome控制台中出现的唯一错误是
我用我的域替换了sub.domain
这些错误出现在第一个请求后几分钟
GET https://sub.domain.com/events net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)
2sub.domain.com/addCart:1 POST https://sub.domain.com/addCart 504 (Gateway Time-out)
(index):1 Access to XMLHttpRequest at 'https://sub.domain.com/addCart' from origin 'https://example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
createError.js:16 Uncaught (in promise) Error: Network Error
at e.exports (createError.js:16)
at XMLHttpRequest.p.onerror (xhr.js:83)
e.exports @ createError.js:16
p.onerror @ xhr.js:83
error (async)
(anonymous) @ xhr.js:80
e.exports @ xhr.js:12
e.exports @ dispatchRequest.js:50
Promise.then (async)
u.request @ Axios.js:61
r.forEach.u.<computed> @ Axios.js:86
(anonymous) @ bind.js:9
value @ index.js:156
state.listening.EventSource.onmessage @ index.js:121
index.js:114 {"client":1579885346578}
index.js:150 send
sub.domain.com/events:1 GET https://sub.domain.com/events net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)
2sub.domain.com/addCart:1 POST https://sub.domain.com/addCart net::ERR_ABORTED 504 (Gateway Time-out)
正如Darren Cook在这里所描述的,您需要禁用服务器端的缓冲。在响应标头中添加“X-Accel-Buffering”参数并将其设置为“no”,为我解决了这个问题。
const headers = {
'Content-Type': 'text/event-stream',
'Connection': 'keep-alive',
'Cache-Control': 'no-cache',
'X-Accel-Buffering': 'no'
};
我有一个ASP。net core 3.1服务器项目,它有一个非常简单的API发送单向服务器发送事件(SSE),如下所示: 现在,我想通过C#UWP客户端接收这些事件。很遗憾,我只收到第一个事件: 如何在UWP中创建行为以始终监听该连接并接收我可以进一步处理的事件?
我无法理解HTML5s服务器发送的事件是否真的适合ReST体系结构。我知道并非HTML5/HTTP的所有方面都需要适合ReST架构。但我想从专家那里知道HTTP的哪一半是SSE(ReSTful的一半还是另一半!)。 一种观点是它是ReSTful的,因为客户端向服务器发出了一个“初始”HTTP GET请求,其余的只能看作是不同内容类型的部分内容响应(“文本/事件流”) 发送的请求不知道有多少响应将作
我想要实现的是: user1向服务器发送消息(一个简单的POST请求) 服务器部分是(events.php) 我在(true)时尝试了无限循环以避免3秒的轮询。我也尝试过没有那个无限循环。只有发送消息的用户收到事件。 我理解这种做法并不好。但是,将SSE用于聊天应用程序的最佳实践是什么? 如何向所有用户发送事件?
我正在尝试使用泽西岛的JavaScript SSE。我的资源中有以下代码。我在Java7和Tomcat 7上托管。我没有收到任何错误。但我也没有在页面上看到数据。 我调用发布数据。它确实显示信息。但客户什么都没有。在Firefox中,我确实看到事件多次触发。 这是我使用的参考。https://jersey.java.net/documentation/latest/sse.html 我的Index
整个应该由管理(其中大多数请求与业务相关),还是应该由某个完全专用于处理的管理?目前,所有业务请求和SSE事件都由处理。 如何在集群环境中应用主动-主动模式(=master-master),其中请求在实例之间随机路由? 如果您有更多有用的信息(和注意事项),请随时分享!
使用系统将“服务器发送事件(SSE)样式”事件流式传输到F#中的前端的轻量级方式是什么。网Http库?我了解事件流格式(例如,这个PHP示例代码),但我正在寻求一些指导,以便在服务器端F#应用程序(我在.Net Framework 4.8上)中实现流部分。