[英]Suave with f# - How to have a rest api and websocket port in an f# chat application?
I have an f# chat application that needs rest apis exposed as well as have websockets for real time messaging.我有一个 f# 聊天应用程序,它需要暴露 rest api 以及用于实时消息传递的 websocket。 I am using Suave framework.我正在使用 Suave 框架。
I have a frontend which has a "Chat" button that runs javascript on click.我有一个前端,它有一个“聊天”按钮,点击时运行 javascript。 The javascript triggers the creates a web socket for the websocket url (/websocket) and establishes a connection for the real time chats. The javascript triggers the creates a web socket for the websocket url (/websocket) and establishes a connection for the real time chats. However, I have another button "FetchUsers" for fetching all the users in the system.但是,我有另一个按钮“FetchUsers”用于获取系统中的所有用户。 But for this, I will need a different path (/people).但为此,我需要一条不同的路径(/people)。 I dont think I can use the (/websocket) path because in the backend, there is only one function which can be defined for a particular path.我不认为我可以使用 (/websocket) 路径,因为在后端,只有一个 function 可以为特定路径定义。
To achieve this I have come up with the idea that I could expose 2 different ports: one for the rest api and one for the web sockets. To achieve this I have come up with the idea that I could expose 2 different ports: one for the rest api and one for the web sockets. My rest api (localhost:8082/people) is used to get all the users in the system and the web sockets (localhost:8080/websocket) is for sending chat messages to all users in the system My rest api (localhost:8082/people) is used to get all the users in the system and the web sockets (localhost:8080/websocket) is for sending chat messages to all users in the system
I am open to any other suggestions as to how can I implement the chat application.对于如何实现聊天应用程序,我愿意接受任何其他建议。
Program.fs程序.fs
let app : WebPart =
choose [
path "/websocket" >=> handShake ws
path "/websocketWithSubprotocol" >=> handShakeWithSubprotocol (chooseSubprotocol "test") ws
path "/websocketWithError" >=> handShake wsWithErrorHandling
GET >=> choose [ path "/" >=> file "index.html"; browseHome ]
NOT_FOUND "Found no handlers." ]
let myCfg =
{ defaultConfig with
bindings = [
HttpBinding.createSimple HTTP "127.0.0.1" 8080
HttpBinding.createSimple HTTP "127.0.0.1" 8082
]
}
[<EntryPoint>]
let main _ =
let personWebPart = rest "people" {
GetAll = Db.getPeople
Create = Db.createPerson
}
startWebServer myCfg personWebPart
startWebServer myCfg app
Restful.fs Restful.fs
module RestFul =
open Suave.Web
open Suave.Successful
open Newtonsoft.Json
open Suave
open Suave.Operators
open Suave.Filters
open Suave.Files
open Suave.RequestErrors
open Newtonsoft.Json.Serialization
type RestResource<'a> = {
GetAll : unit -> 'a seq
Create : 'a -> 'a
}
let fromJson<'a> json =
JsonConvert.DeserializeObject(json, typeof<'a>) :?> 'a
let getResourceFromReq<'a> (req : HttpRequest) =
let getString (rawForm: byte[]) =
System.Text.Encoding.UTF8.GetString(rawForm)
req.rawForm |> getString |> fromJson<'a>
let JSON v =
let jsonSerializerSettings = JsonSerializerSettings()
jsonSerializerSettings.ContractResolver <- CamelCasePropertyNamesContractResolver()
JsonConvert.SerializeObject(v, jsonSerializerSettings)
|> OK
>=> Writers.setMimeType "application/json; charset=utf-8"
let rest resourceName resource =
let resourcePath = "/" + resourceName
let getAll = warbler (fun _ -> resource.GetAll () |> JSON)
path resourcePath >=> choose [
GET >=> getAll
POST >=> request (getResourceFromReq >> resource.Create >> JSON)
]
How can assign the websocket to port 8080 and rest api to port 8082?如何将 websocket 分配到端口 8080 和 rest api 分配到端口 8082? I am doing this for now.我现在正在这样做。 The server starts up on the ports but I am only able to access the rest url ie localhost:8080/people服务器在端口上启动,但我只能访问 rest url 即 localhost:8080/people
startWebServer myCfg personWebPart
startWebServer myCfg app
Reiterating my previous point, I would like to know any other approaches as to how can I implement the chat application.重申我之前的观点,我想知道关于如何实现聊天应用程序的任何其他方法。
It has been awhile since I've used Suave but if I recall it has WebSocket support using a custom "socket" computation expression.我使用 Suave 已经有一段时间了,但如果我记得它使用自定义“套接字”计算表达式支持 WebSocket。 You loop in the expression, wait for a message, and then handle it.您在表达式中循环,等待消息,然后处理它。 Note that waiting on the Websocket is in itself an async operation and that each client has their own loop.请注意,等待 Websocket 本身就是一个异步操作,每个客户端都有自己的循环。
Example is on their Github: https://github.com/SuaveIO/suave/blob/master/examples/WebSocket/Program.fs示例在他们的 Github 上: https://github.com/SuaveIO/suave/blob/master/examples/WebSocket/Program.fs
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.