मुझे डेटा स्ट्रीमिंग के साथ कुछ समस्या है डेटा सर्वर के नियमित हिस्से को फ्लश करते समय इसे इसकी लंबाई के साथ भेजता है जो वास्तव में डेटा स्ट्रीम को दूषित करता है।
(एम्बेडेड जेटी और एम्बेडेड टोमकैट एक ही परिणाम उत्पन्न करता है।)
मैं एक क्लाइंट के रूप में netty का उपयोग कर रहा हूं और यह संख्या को आने वाले खंड के पहले बाइट्स के रूप में लॉग करता है (नियमित रेखाएं \ n \ r से अलग होती हैं)। इसके अलावा घाट का लकड़हारा
DEBUG org.eclipse.jetty.io.WriteFlusher - write: WriteFlusher@ ... [HeapByteBuffer@ ... {<<<\r\n26\r\n>>>...},DirectByteBuffer@...{<<<event: put\ndata:{...rty':'value'}\n\n>>>...}]
कहां
"\r\n26\r\n" - संदेश की लंबाई का एक HEX प्रतिनिधित्व है
"ईवेंट: put\nडेटा:{...rty':'value'}\n\n" - वास्तव में भेजा गया संदेश
मैं लंबाई हस्तांतरण कैसे बंद कर सकता हूं?
कोड:
public class TestCorruptedWrites {
private static Server server = null;
private final static int port = 8089;
private final static String endpoint = "/test";
static String message = "event: put\ndata:{'property':'value'}\n\n";
private static void sleep(int millis){
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@BeforeClass
public static void initMockServer() throws Exception {
System.out.println(message.length());
final ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
contextHandler.addServlet(new ServletHolder(new HttpServlet() {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
resp.flushBuffer();
Writer writer = resp.getWriter();
while (true) {
writer.write(message);
writer.flush();
sleep(300);
}
}
}), endpoint);
contextHandler.setContextPath("/");
server = new Server(new QueuedThreadPool(50, 10));
ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory());
connector.setPort(port);
server.addConnector(connector);
server.setHandler(contextHandler);
server.start();
}
@Test
public void testClient() throws InterruptedException, IOException {
InternalLoggerFactory.setDefaultFactory(new Slf4JLoggerFactory());
final Bootstrap bootstrap = new Bootstrap();
final URI uri = URI.create("http://localhost:" + port + endpoint);
bootstrap
.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(uri.getHost(), uri.getPort()))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast("logger", new LoggingHandler(LogLevel.DEBUG));
pipeline.addLast("line", new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()));
pipeline.addLast("string", new StringDecoder());
pipeline.addLast("encoder", new HttpRequestEncoder());
pipeline.addLast("log", new SimpleChannelInboundHandler<String>(){
@Override
protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println(" ---> " + msg);
}
@Override
public void channelActive(ChannelHandlerContext context) {
System.out.println("active!");
HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri.toString());
request.headers().add(HttpHeaders.Names.ACCEPT, "text/event-stream");
request.headers().add(HttpHeaders.Names.HOST, uri.getHost());
request.headers().add(HttpHeaders.Names.ORIGIN, "http://" + uri.getHost());
context.channel().writeAndFlush(request);
}
});
}
})
.connect();
Thread.sleep(500_000);
}
}
निर्भरताएँ:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.4.2.v20170220</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
1 उत्तर
वह मानक HTTP/1.1 चंकिंग ट्रांसफर एन्कोडिंग है जिसे आप देख रहे हैं।
चंकिंग तब होती है जब आपके पास Content-Length
हेडर के बिना कोई प्रतिक्रिया होती है, और कनेक्शन लगातार बने रहना है (प्रति HTTP / 1.1 कल्पना)।
यदि आपके पास HTTP/1.1 क्लाइंट है, और सर्वर साइड पर Content-Length
हेडर सेट नहीं कर सकते हैं, तो Connection: close
अनुरोध और/या प्रतिक्रिया शीर्षलेख सेट करने पर विचार करें, क्योंकि यह लगातार कनेक्शन मोड को रद्द कर देगा जो ट्रिगर करता है खंडित स्थानांतरण एन्कोडिंग।
सलाह: चंकड ट्रांसफर एन्कोडिंग का समर्थन करना स्मार्ट होगा, जैसा कि आप देख सकते हैं कि किसी भी संख्या में स्थानों (यहां तक कि प्रॉक्सी!)
संबंधित सवाल
नए सवाल
java
जावा एक उच्च स्तरीय प्रोग्रामिंग भाषा है। इस टैग का उपयोग तब करें जब आपको भाषा का उपयोग करने या समझने में समस्या हो। इस टैग का उपयोग शायद ही कभी किया जाता है और इसका उपयोग अक्सर [वसंत], [वसंत-बूट], [जकार्ता-ई], [Android], [javafx], [हडूप], [श्रेणी] और [मावेन] के साथ किया जाता है।