diff --git a/feed.go b/feed.go new file mode 100644 index 0000000..fe48170 --- /dev/null +++ b/feed.go @@ -0,0 +1,14 @@ +package main + +type feed struct { + Title string `json:"title,omitempty"` + Link string `json:"link"` + Custom map[string]string `json:"custom,omitempty"` + Items []item `json:"items,omitempty"` +} + +type item struct { + Title string `json:"title"` + Link string `json:"link"` + Description string `json:"description"` +} diff --git a/main.go b/main.go index 62b16a6..9c5ca5f 100644 --- a/main.go +++ b/main.go @@ -20,9 +20,10 @@ type Config struct { } var ( - dbMap sync.Map + dbMap map[string]feed rssUrls Config upgrader = websocket.Upgrader{} + lock sync.RWMutex //go:embed static dirStatic embed.FS @@ -48,6 +49,8 @@ func init() { if err != nil { panic(err) } + + dbMap = make(map[string]feed) } func main() { @@ -73,15 +76,24 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { log.Printf("Upgrade failed: %v", err) return } + defer conn.Close() for { for _, url := range rssUrls.Values { - feedJSON, ok := dbMap.Load(url) + lock.RLock() + cache, ok := dbMap[url] + lock.RUnlock() if !ok { log.Printf("Error getting feed from db is null %v", url) continue } - err = conn.WriteMessage(websocket.TextMessage, []byte(feedJSON.(string))) + data, err := json.Marshal(cache) + if err != nil { + log.Printf("json marshal failure: %s", err.Error()) + continue + } + + err = conn.WriteMessage(websocket.TextMessage, data) //错误直接关闭更新 if err != nil { log.Printf("Error sending message or Connection closed: %v", err) @@ -111,39 +123,41 @@ func updateFeeds() { } func updateFeed(fp *gofeed.Parser, url, formattedTime string) { - feed, err := fp.ParseURL(url) + result, err := fp.ParseURL(url) if err != nil { log.Printf("Error fetching feed: %v | %v", url, err) return } - - feed.Custom = map[string]string{"lastupdate": formattedTime} - - feedJSON, err := json.Marshal(feed) - if err != nil { - log.Printf("Error marshaling feed: %v", err) - return + customFeed := feed{ + Title: result.Title, + Link: result.Link, + Custom: map[string]string{"lastupdate": formattedTime}, + Items: make([]item, 0, len(result.Items)), } - dbMap.Store(url, string(feedJSON)) + for _, v := range result.Items { + customFeed.Items = append(customFeed.Items, item{ + Link: v.Link, + Title: v.Title, + Description: v.Description, + }) + } + lock.Lock() + defer lock.Unlock() + dbMap[url] = customFeed } func getFeedsHandler(w http.ResponseWriter, r *http.Request) { - - feeds := make([]gofeed.Feed, 0, len(rssUrls.Values)) + feeds := make([]feed, 0, len(rssUrls.Values)) for _, url := range rssUrls.Values { - feedJSON, ok := dbMap.Load(url) + lock.RLock() + cache, ok := dbMap[url] + lock.RUnlock() if !ok { log.Printf("Error getting feed from db is null %v", url) continue } - var feed gofeed.Feed - if err := json.Unmarshal([]byte(feedJSON.(string)), &feed); err != nil { - log.Printf("Error unmarshaling feed: %v", err) - continue - } - - feeds = append(feeds, feed) + feeds = append(feeds, cache) } w.Header().Set("Content-Type", "application/json")