stck-nsq-msg.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package stcknsqmsg
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net"
  6. "os"
  7. "stck/stck-nsq-msg/msg"
  8. "github.com/denisbrodbeck/machineid"
  9. "github.com/go-viper/mapstructure/v2"
  10. )
  11. type StckNsqMsg struct {
  12. Type string `mapstructure:"type"`
  13. Data StckNsqMsgVariant `mapstructure:"data"`
  14. }
  15. type StckNsqMsgRaw struct {
  16. Type string `mapstructure:"type"`
  17. Data map[string]interface{} `mapstructure:"data"`
  18. }
  19. type StckNsqMsgVariant interface {
  20. MsgType() string
  21. }
  22. func (m *StckNsqMsg) ToString() (string, error) {
  23. b, err := json.Marshal(m)
  24. if err != nil {
  25. return "", err
  26. }
  27. return string(b), nil
  28. }
  29. func FromString(s string) (StckNsqMsg, error) {
  30. var rm StckNsqMsgRaw
  31. var m StckNsqMsg
  32. err := json.Unmarshal([]byte(s), &rm)
  33. if err != nil {
  34. return m, err
  35. }
  36. // Cast to strongly typed struct
  37. m.Type = rm.Type
  38. switch rm.Type {
  39. case msg.DeviceHeartbeatMsgType:
  40. var d msg.DeviceHeartbeatMsg
  41. err = mapstructure.Decode(rm.Data, &d)
  42. if err != nil {
  43. return m, err
  44. }
  45. m.Data = &d
  46. default:
  47. return m, fmt.Errorf("unknown message type: %s", rm.Type)
  48. }
  49. return m, nil
  50. }
  51. func DeviceIdMatches(id1, id2 string) bool {
  52. return id1 == id2 || id1 == "*" || id2 == "*"
  53. }
  54. func GetLocalIP() (net.IP, error) {
  55. ifaces, err := net.Interfaces()
  56. if err != nil {
  57. return nil, err
  58. }
  59. for _, iface := range ifaces {
  60. addrs, err := iface.Addrs()
  61. if err != nil {
  62. return nil, err
  63. }
  64. for _, addr := range addrs {
  65. var ip net.IP
  66. switch v := addr.(type) {
  67. case *net.IPNet:
  68. ip = v.IP
  69. case *net.IPAddr:
  70. ip = v.IP
  71. }
  72. if ip == nil || ip.IsLoopback() {
  73. continue
  74. }
  75. ip = ip.To4()
  76. if ip == nil {
  77. continue // not an ipv4 address
  78. }
  79. return ip, nil
  80. }
  81. }
  82. return nil, fmt.Errorf("no non-loopback IP address found")
  83. }
  84. func MakeUniqueMachineID() string {
  85. ip, err := GetLocalIP()
  86. if err != nil {
  87. fmt.Fprintf(os.Stderr, "get local IP failed: %v\n", err)
  88. }
  89. machineid, err := machineid.ProtectedID("unique")
  90. if err != nil {
  91. fmt.Fprintf(os.Stderr, "get machine ID failed: %v\n", err)
  92. }
  93. return fmt.Sprintf("%s-%s", ip.String(), machineid)
  94. }