首页
关于
Search
1
联想510s mini 安装 Ventura
935 阅读
2
基于K8s + Jenkins+Docker + Gitee 自动部署 - 配置 Jenkins Item + Gitee Webhook (二)
587 阅读
3
Spring Boot Schedule疑问及线程池配置
488 阅读
4
Server Send Events With Spring Boot
433 阅读
5
Ngrok使用自有服务器服务器及域名 - 解决Mac client问题
413 阅读
默认分类
SSH
typecho
Spring boot
其他
mysql
k8s
jenkins
docker
Java
mqtt
MongoDB
登录
/
注册
Search
标签搜索
k8s
docker
ssh
mysql
db
gitee
jenkins
ngrok
黑苹果
MQTT
CC
累计撰写
19
篇文章
累计收到
1
条评论
首页
栏目
默认分类
SSH
typecho
Spring boot
其他
mysql
k8s
jenkins
docker
Java
mqtt
MongoDB
页面
关于
搜索到
4
篇与
其他
的结果
2023-04-02
Server Send Events With Spring Boot
背景在使用ChatGPT时,通过http.Post进行调用耗时非常高,体验较差。 OpenAI提供了Stream(即SSE)的返回模式,不用等到响应生成完后才给到客户端响应。使用Stream API方式时,那么后端与前端也需要使用SSE的方式进行API交互。源代码在文末。Server-Sent Events(SSE)是一种在Web浏览器和服务器之间实现服务器推送事件的技术。它允许服务器向客户端推送事件流,这些事件可以是简单的文本消息或具有自定义格式的复杂数据。SSE 是一种基于 HTTP 的协议,使用长轮询或 HTTP 流来实现服务器推送。 SSE 可以用于各种用例,例如实时更新股票报价、即时聊天应用程序、新闻或社交媒体网站上的实时更新等等。与传统的轮询或 WebSocket 不同,SSE 不需要客户端发起请求,而是服务器始终保持连接打开并推送数据,因此 SSE 可以更高效地使用网络带宽和服务器资源。 在前端,可以使用 JavaScript API 来监听服务器发送的事件,以及处理和显示这些事件的数据。 引用:## open ai chat api https://platform.openai.com/docs/api-reference/chat/create ## Request ChatGPT API Using Spring boot https://www.taogenjia.com/2023/03/16/The-Guide-to-Call-ChatGPT-3-5-Event-Stream-API-in-Spring-Boot/ ## Doc https://developer.mozilla.org/en-US/docs/web/api/server-sent_events/using_server-sent_events https://developer.mozilla.org/zh-CN/docs/Web/API/EventSource ## nginx https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering理解常见的HTTP请求是服务端把命令执行完成过后给到一个结果,那么客户端必须等待,大部分场景下这是没问题的。 那么在处理时间比较高的场景下,客户端可以实时接收部分处理结果,增加用户体验。我们从另一个角度看Http,HttpServerRequest: 有输入流,包含请求的数据HttpServletResponse:有输出流,可以写响应数据。那么我们处理Http请求时,不断的向Response的 outputStream写入数据,那么在没有处理完成响应的情况下也可以收到一部分数据。 @GetMapping("test") public void test(HttpServletRequest request, HttpServletResponse response) throws Exception { // 设置响应的Content-Type为text/event-stream response.setContentType("text/event-stream"); response.setStatus(200); OutputStream outputStream = response.getOutputStream(); int i = 10; while (i >= 0) { String message = "i : " + i + "\n"; outputStream.write(message.getBytes(StandardCharsets.UTF_8)); outputStream.flush(); try { Thread.sleep(1000); } catch (Exception ignored) {} i--; } }我们打开浏览器访问这个api时,界面会间隔一秒输出一行:i : 10 i : 9 i : 8 i : 7 i : 6 i : 5 i : 4 i : 3 i : 2 i : 1 i : 0点击查看效果有了以上理解,我们只需要按着SSE要求的格式不停的向写入数据即可。SSE 格式1、id event dataid: xxx \n event: message \n data: hello from cc\n\n2、event dataevent: message \n data: hello from cc\n\n3、data onlydata: hello from cc\n\n其中: event: 事件名称,可以自己定义,默认是message id、event: 可选4、结束推送 如果使用sse,需要服务端进行关闭,如果不关闭前端会不停的重试(retry)自定义事件event: close \n data:\n\n前端订阅然后close,然后关闭sse const sse = new EventSource('/api/sse'); /* * 自定义订阅 */ sse.addEventListener("close", function(e) { sse.close(); }) /* This will listen only for events * similar to the following: * * event: notice * data: useful data * id: someid * */ sse.addEventListener("notice", function(e) { console.log(e.data) }) /* Similarly, this will listen for events * with the field `event: update` */ sse.addEventListener("update", function(e) { console.log(e.data) }) /* The event "message" is a special case, as it * will capture events without an event field * as well as events that have the specific type * `event: message` It will not trigger on any * other event type. */ sse.addEventListener("message", function(e) { console.log(e.data) })发送特殊标记的datadata: [DONE]\n\n处理 '[DONE]'的message const sse = new EventSource('/api/sse'); /* The event "message" is a special case, as it * will capture events without an event field * as well as events that have the specific type * `event: message` It will not trigger on any * other event type. */ sse.addEventListener("message", function(e) { var data = e.data; if (data.contains('[DONE]')) { sse.close() } else { console.log(data) } })踩坑1、使用Nginx部署后,消息没有一个一个收到,而是在处理完成后整个返回修改 nginxlocation / { proxy_pass http://127.0.0.1:xxx/; ... # When buffering is disabled, the response is passed to a client synchronously, immediately as # it is received. nginx will not try to read the whole response from the proxied server. The # maximum size of the data that nginx can receive from the server at a time is set by the # proxy_buffer_size directive. proxy_buffering off; ... }2、如果使用了WebFiler,需要开启asyncSupported @WebFilter(urlPatterns = "*",asyncSupported = true) public class SomeFilter implements Filter { .... }源代码https://gitee.com/pchenc/sse-demo
2023年04月02日
433 阅读
0 评论
1 点赞
2023-03-27
摘自-《幸福之路》
“我想我能变成动物,和它们为伴,它们是那么恬静那么矜持,我站着,久久的望着它们。它们不为儿女作牛马,也不为几女哀号,它们不在黑暗里睁眼失眠,为了它们的罪过啼泣,它们不喋喋讨论对上帝的责任,使我头晕脑胀,没有一个不满,没有一个为了占有欲而癲狂,没有一个向另一个屈膝,也不对几千年前的袓先跪拜,在整个的地球上没有一个有什么身份,也没有一个忧郁哀伤。——惠特曼Walt Whitman”摘录来自幸福之路罗素此材料可能受版权保护。“而过事诛求的结果,一定使你连应得的一份都落空。一个人能凭藉一些真正的兴趣,例如德朗会议或星辰史等,而忘记他的烦虑的话,当他从无人格的世界上旅行回来时,定将发觉自己觅得了均衡与宁静,使他能用最高明的手段去对付他的烦虑,而同时也尝到了真正的、即使是暂时的幸福。 幸福底秘诀是:让你的兴趣尽量的扩大,让你对人对物的反应,尽量的倾向于友善。”摘录来自: 罗素. “幸福之路 (傅雷经典译文全集).” Apple Books. 此材料受版权保护。
2023年03月27日
215 阅读
0 评论
0 点赞
2022-06-24
Ngrok使用自有服务器服务器及域名 - 解决Mac client问题
环境服务端:Linux客户端:Linux、Mac要求:服务器有公网ip+自有域名编译服务端参考:https://www.jianshu.com/p/1fafa10af189完成后,可得到Linux、Windows对应的Server、Client域名解析可以使用子域名,如: ngrok.xx.com; 具体tunnel: xx.ngrok.xx.com这里需要配置两个域名解析ngrok.xx.com ip *.ngrok.xx.com ip (泛域名解析)问题编译Mac os client:GOOS=linux GOARCH=amd64 make release-client该命令能正常编译通过,但在Mac os中不能正常运行:chen@cc darwin_amd64 % ngrok fatal error: runtime: bsdthread_register error runtime stack: runtime.throw(0x14e8431, 0x21) /usr/local/go/src/runtime/panic.go:596 +0x95 fp=0x7ff7bfeff7d0 sp=0x7ff7bfeff7b0 runtime.goenvs() /usr/local/go/src/runtime/os_darwin.go:108 +0xa0 fp=0x7ff7bfeff800 sp=0x7ff7bfeff7d0 runtime.schedinit() /usr/local/go/src/runtime/proc.go:486 +0xa1 fp=0x7ff7bfeff840 sp=0x7ff7bfeff800 runtime.rt0_go(0x7ff7bfeff870, 0x1, 0x7ff7bfeff870, 0x1000000, 0x1, 0x7ff7bfeff9d0, 0x0, 0x7ff7bfeff9d6, 0x7ff7bfeff9f2, 0x7ff7bfeffa01, ...) /usr/local/go/src/runtime/asm_amd64.s:158 +0x183 fp=0x7ff7bfeff848 sp=0x7ff7bfeff840 编译Mac客户端要求:Macbook1、将编译服务端的代码拷贝到Mac # client 需要使用与服务端一样的证书chen@cc ngrok % ls CONTRIBUTORS LICENSE Makefile README.md assets bin contrib docs pkg src2、删除源码中 bin 目录 # 服务端编译产生的文件rm -rf bin/*3、安装1.14.1 版本Gohttps://dl.google.com/go/go1.14.1.darwin-amd64.pkg4、编译客户端GOOS=darwin GOARCH=amd64 make release-client5、验证chen@cc ngrok % bin/ngrok Error: Specify a local port to tunnel to, or an ngrok command. Example: To expose port 80, run 'ngrok 80' 提示ngrok可执行,增加配置即可使用遇到的问题:1、ngrok客户端在Mac运行无法创建链接,日志提示:ngrok certificate relies on legacy Common Name field, use SANs instead 使用Go 1.14.1版本进行重编编译2、编译出现错误:malformed module path "ngrok": missing dot in first path elementchen@cc ngrok % GOOS=darwin GOARCH=amd64 make release-server GOOS="" GOARCH="" go get github.com/jteeuwen/go-bindata/go-bindata go: downloading github.com/jteeuwen/go-bindata v3.0.7+incompatible go get: installing executables with 'go get' in module mode is deprecated. Use 'go install pkg@version' instead. For more information, see https://golang.org/doc/go-get-install-deprecation or run 'go help get' or 'go help install'. bin/go-bindata -nomemcopy -pkg=assets -tags=release \ -debug=false \ -o=src/ngrok/client/assets/assets_release.go \ assets/client/... bin/go-bindata -nomemcopy -pkg=assets -tags=release \ -debug=false \ -o=src/ngrok/server/assets/assets_release.go \ assets/server/... go get -tags 'release' -d -v ngrok/... go get ngrok/...: malformed module path "ngrok": missing dot in first path element make: *** [deps] Error 1配置环境变量: export GO111MODULE=off引用:https://zhuanlan.zhihu.com/p/374372749https://github.com/golang/go/issues/350483、编译出现错误:...proxy.golang.org..... i/o timeout切换代理:go env -w GOPROXY=https://goproxy.cn\n引用:https://blog.csdn.net/wei11556/article/details/109526797
2022年06月24日
413 阅读
0 评论
0 点赞
2022-04-25
生活
为什么就这样了?
2022年04月25日
197 阅读
0 评论
0 点赞