ssevent.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package render
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "reflect"
  7. )
  8. type sseRender struct{}
  9. var SSEvent Render = sseRender{}
  10. func (_ sseRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  11. eventName := data[0].(string)
  12. obj := data[1]
  13. return WriteSSEvent(w, eventName, obj)
  14. }
  15. func WriteSSEvent(w http.ResponseWriter, eventName string, data interface{}) error {
  16. header := w.Header()
  17. if len(header.Get("Content-Type")) == 0 {
  18. w.Header().Set("Content-Type", "text/event-stream")
  19. }
  20. var stringData string
  21. switch typeOfData(data) {
  22. case reflect.Struct, reflect.Slice, reflect.Map:
  23. if jsonBytes, err := json.Marshal(data); err == nil {
  24. stringData = string(jsonBytes)
  25. } else {
  26. return err
  27. }
  28. case reflect.Ptr:
  29. stringData = escape(fmt.Sprintf("%v", &data))
  30. default:
  31. stringData = escape(fmt.Sprintf("%v", data))
  32. }
  33. _, err := fmt.Fprintf(w, "event: %s\ndata: %s\n\n", escape(eventName), stringData)
  34. return err
  35. }
  36. func typeOfData(data interface{}) reflect.Kind {
  37. value := reflect.ValueOf(data)
  38. valueType := value.Kind()
  39. if valueType == reflect.Ptr {
  40. newValue := value.Elem().Kind()
  41. fmt.Println(newValue)
  42. if newValue == reflect.Struct ||
  43. newValue == reflect.Slice ||
  44. newValue == reflect.Map {
  45. return newValue
  46. } else {
  47. return valueType
  48. }
  49. }
  50. return valueType
  51. }
  52. func escape(str string) string {
  53. return str
  54. }