generated from prairir/project-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add heartbeat, init state, and wait state
Add heartbeat function. Add init state. Add wait state. Add support values to config
- Loading branch information
Showing
6 changed files
with
177 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package heartbeat | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/gorilla/websocket" | ||
"github.com/prairir/imacry/pkg/config" | ||
) | ||
|
||
// heartbeat.HeartBeat: | ||
func HeartBeat() { | ||
for { | ||
err := config.Config.Conn.WriteMessage(websocket.TextMessage, []byte("hb:")) | ||
if err != nil { | ||
config.Config.HBError <- fmt.Errorf("heartbeat.HeartBeat error: %w", err) | ||
return | ||
} | ||
|
||
mt, message, err := config.Config.Conn.ReadMessage() | ||
if err != nil { | ||
config.Config.HBError <- fmt.Errorf("heartbeat.HeartBeat error: %w", err) | ||
return | ||
} | ||
|
||
fmt.Println(string(message)) | ||
|
||
// if its a text message and the message is `hb: 1` | ||
// close the signal channel and exit | ||
// else if its a text message and the message is `hb: 0` | ||
// continue | ||
if mt == websocket.TextMessage && string(message[:5]) == "hb: 1" { | ||
close(config.Config.Signal) | ||
return | ||
} else if mt == websocket.TextMessage && string(message[:5]) == "hb: 0" { | ||
continue | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package state | ||
|
||
import ( | ||
"fmt" | ||
"net/url" | ||
|
||
"github.com/gorilla/websocket" | ||
"github.com/prairir/imacry/pkg/config" | ||
"github.com/prairir/imacry/pkg/heartbeat" | ||
) | ||
|
||
// state.Init: the initialization state | ||
// It connects to the server, gets the password(if one wasnt provided), | ||
// sets up channel for trigger event, sets up channel for hb error, | ||
// start the heartbeat goroutine, and sets the next state | ||
// | ||
// params: the next state | ||
// returns: error | ||
func Init(nextState config.State) error { | ||
// the url to connect to the server | ||
url := url.URL{ | ||
Scheme: "ws", | ||
Host: config.Config.Address, | ||
Path: "/", | ||
} | ||
|
||
conn, _, err := websocket.DefaultDialer.Dial(url.String(), nil) | ||
if err != nil { | ||
return fmt.Errorf("state.Init error: %w", err) | ||
} | ||
|
||
// if the password doesnt exist | ||
// get it from server | ||
if config.Config.Password == "" { | ||
err = conn.WriteMessage(websocket.TextMessage, []byte("init:")) | ||
if err != nil { | ||
return fmt.Errorf("state.Init error: %w", err) | ||
} | ||
|
||
mt, message, err := conn.ReadMessage() | ||
if err != nil { | ||
return fmt.Errorf("state.Init error: %w", err) | ||
} | ||
|
||
// if its a text message and starts with `pass:` then make the rest the password | ||
// else return an error | ||
fmt.Println(string(message)) | ||
if mt == websocket.TextMessage && string(message[:5]) == "pass:" { | ||
config.Config.Password = string(message[6:]) | ||
} else { | ||
return fmt.Errorf("state.Init error: Bad response from server") | ||
} | ||
|
||
} | ||
|
||
// set the global connection to this connection | ||
config.Config.Conn = conn | ||
|
||
// signal channel | ||
// when this is closed, they can read to it meaning that an event | ||
// happened | ||
config.Config.Signal = make(chan struct{}) | ||
|
||
// error channel | ||
// when this is populated | ||
// print error and die | ||
config.Config.HBError = make(chan error, 1) | ||
|
||
// launch the heartbeat system in a goroutine | ||
go heartbeat.HeartBeat() | ||
|
||
// after were finished, set the state to the next one | ||
config.Config.State = nextState | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package state | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/prairir/imacry/pkg/config" | ||
) | ||
|
||
// state.Wait: the wait state which waits for either an error or a signal | ||
// from the heartbeat goroutine. if it gets a signal, move to next nextState. | ||
// if gets an error, return it. | ||
// | ||
// params: the next state | ||
// returns: error | ||
func Wait(nextState config.State) error { | ||
// loop over forever | ||
for { | ||
// if you can read from signal(like when its closed) | ||
// set the next state and exit | ||
// | ||
// if you can read an error | ||
// return the error | ||
// | ||
// if you can do either, try again | ||
select { | ||
case <-config.Config.Signal: | ||
config.Config.State = nextState | ||
return nil | ||
case err := <-config.Config.HBError: | ||
return fmt.Errorf("state.Wait error: %w", err) | ||
default: | ||
continue | ||
} | ||
} | ||
} |