Giter VIP home page Giter VIP logo

ikisocket's Introduction

Hi there ๐Ÿ‘‹

  • ๐Ÿ‘‹ Hi, Iโ€™m Antonio, Full-Stack developer, and passionate architect ๐Ÿช›
  • ๐Ÿ‘€ Iโ€™m interested in Golang, PHP, Node.js ๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป I'm also passionate about mobile development like Ionic (Angular) and Swift ๐Ÿ“ฑ
  • ๐Ÿ’ž๏ธ Drop me a line if you have project and you want to work together
  • ๐Ÿ“ซ You can reach me here ๐Ÿฆ Twitter or โœ‰๏ธ Mail

Technologies

Go TypeScript PHP JavaScript NodeJS Nest.js MySQL SQLite ArangoDB

ikisocket's People

Contributors

antoniodipinto avatar crgao avatar dependabot[bot] avatar dmorawetz avatar jibon57 avatar kayode0x avatar ramiberm avatar whizdummy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ikisocket's Issues

426 Upgrade Required

I copied the code from the example into my test server. It worked fine on localhost using https://www.websocket.org/echo.html, but when I deployed it and used wss://api.nv7haven.tk/ws/123?v=1.0, it is returning a 426. I put a print statement, and its returning a 426 because IsWebsocketUpgrade is returning false. Why is it returning false, and how can I fix this?

Allow Access to ws variable

Is your feature request related to a problem? Please describe.
I am trying to set Read Deadline everytime I receive a ping/pong to keep the connection alive. By default, it is 15 minutes which seems long. I wanted to set the read deadline using ws.SetReadDeadline but looks like ws is not available to accessed from outside.

Describe the solution you'd like
Allow ws to be accessed from outside as Ws

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Connection with gofiber

hi, iยดm rene (maintainer of the gofiber project)

to enable gofiber users to find your work, we should add the repository to awesome-fiber
can you(@antoniodipinto ) do that?

what do you think about including your work in our contrib repository, either as a separate package or under the websocket package ?

BUG

Describe the bug
panic: interface conversion on function GetStringAttribute / GetIntAttribute can't read null memory

To Reproduce

Check kws.attributes map variable before return interface conversion.

func (kws *Websocket) GetIntAttribute(key string) int {
kws.mu.RLock()
defer kws.mu.RUnlock()
val, ok := kws.attributes[key]
if !ok || val == nil {
return 0
}
return val.(int)
}

func (kws *Websocket) GetStringAttribute(key string) string {
kws.mu.RLock()
defer kws.mu.RUnlock()
val, ok := kws.attributes[key]
if !ok || val == nil {
return ""
}
return val.(string)
}

BUG Ikiscoket panics and crashes server with `close of closed channel`

Describe the bug
Ikisocket panics and crashes the server

To Reproduce
Code:

var GatewayClients = make(map[primitive.ObjectID]string)

func SetupSocketListeners(ctx *context.Context) {
	ikisocket.On(ikisocket.EventMessage, func(ep *ikisocket.EventPayload) {
		message := &struct {
			Token string `json:"token"`
		}{}
		if err := json.Unmarshal(ep.Data, message); err != nil {
			util.GatewayResponse(&gError{})

			ep.Kws.Close()
			return
		}

        // ...

		GatewayClients[usr.Id] = ep.SocketUUID
		ep.Kws.SetAttribute("userId", usr.Id)

		ep.Kws.Emit(util.GatewayResponse(&Message{}), ikisocket.TextMessage)

		ep.Kws.Broadcast(util.GatewayResponse(&Message{}), true, ikisocket.TextMessage)
	})

	ikisocket.On(ikisocket.EventError, func(ep *ikisocket.EventPayload) {
		util.GatewayResponse(&gError{})

		ep.Kws.Close()
	})

	ikisocket.On(ikisocket.EventDisconnect, func(ep *ikisocket.EventPayload) {
		userId, ok := ep.Kws.GetAttribute("userId").(primitive.ObjectID)
		if !ok {
			return
		}

		delete(GatewayClients, userId)
		ep.Kws.SetAttribute("userId", nil)

		ep.Kws.Broadcast(util.GatewayResponse(&Message{}), true, ikisocket.TextMessage)
	})

	ikisocket.On(ikisocket.EventClose, func(ep *ikisocket.EventPayload) {
		userId, ok := ep.Kws.GetAttribute("userId").(primitive.ObjectID)
		if !ok {
			return
		}

		delete(GatewayClients, userId)
		ep.Kws.SetAttribute("userId", nil)

		ep.Kws.Broadcast(util.GatewayResponse(&Message{}), true, ikisocket.TextMessage)
	})

Logs:

panic: close of closed channel

goroutine 261 [running]:
github.com/antoniodipinto/ikisocket.(*Websocket).disconnected(0xc000696af0, {0xec6de0, 0xc000463510})
        /home/xenfo/.asdf/installs/golang/1.19.1/packages/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:563 +0x65
github.com/antoniodipinto/ikisocket.(*Websocket).send(0xc000696af0, {0xecbc38, 0xc000798cc0})
        /home/xenfo/.asdf/installs/golang/1.19.1/packages/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:491 +0x265
created by github.com/antoniodipinto/ikisocket.(*Websocket).run
        /home/xenfo/.asdf/installs/golang/1.19.1/packages/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:507 +0x185

Expected behavior
Ikisocket doesn't crash the server

Additional context
This has only happened once, I was reloading the page and socket wasn't connecting because of this. Not exactly sure how it happened.

BUG: kws.Conn.Headers("user-id") or kws.Params("user-id") not working

Describe the bug
We get empty string for headers and also params for the user id:

	app.Get("/ws", ikisocket.New(func(kws *ikisocket.Websocket) {

		// Retrieve the user id from endpoint
		userId := kws.Params("user-id")
		logrus.Infof("user id: %s", userId)

		// Add the connection to the list of the connected clients
		// The UUID is generated randomly and is the key that allow
		// ikisocket to manage Emit/EmitTo/Broadcast
		clients[userId] = kws.UUID

		// Every websocket connection has an optional session key => value storage
		kws.SetAttribute("user_id", userId)

		//Broadcast to all the connected users the newcomer
		kws.Broadcast([]byte(fmt.Sprintf("New user connected: %s and UUID: %s", userId, kws.UUID)), true)
		//Write welcome message
		kws.Emit([]byte(fmt.Sprintf("Hello user: %s with UUID: %s", userId, kws.UUID)))
	}))

Expected behavior
Should properly grab the user-id from params and headers.

Screenshots
image

Fire event outside a handler

Is your feature request related to a problem? Please describe.
I would like to fire a custom event, when I get a HTTP request.

Describe the solution you'd like
I'd like to do something like ikisocket.Fire("customEvent", "payload") and ikisocket.Broadcast("message")

Describe alternatives you've considered
Alternatively I would have to keep my own map / slice of connected websockets and reimplement your Fire and Broadcast methods.

(Question) How to send message from an outside ikisocket code?

Thanks for this package.

I have one application that uses Gorm to deal with database models, and in there there are callbacks like BeforeCreate or AfterSave...

My question is, how to emit ou send messages from inside these callbacks, or even from regular Fiber endpoints?

Do ikisocket public/global functions do this kind of job?

Not receiving binary data

Describe the bug
Output is auto encoded to string. It is fine if I send data to server but if send data using EmitTo to client then format breaks. It's convert into text.

To Reproduce
Steps to reproduce the behavior:
Try with protocol-buffers to send encoded data from server to client (js). It works fine if encoded with json but not default protocol-buffers encoding.

Expected behavior
Should be able to both sending & receiving binary data

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem here.

ikisocket.New() behavior in chat example

After upgrading to V2 I wanted to try out the chat example.

First, there is a small error for the middleware because of the upgrade. It should now look like this:

	// Setup the middleware to retrieve the data sent in first GET request
	app.Use(func(c *fiber.Ctx) error {
		c.Locals("user_id", c.Query("user_id"))
		return c.Next()
	})

In the example all the callbacks defined with ikisocket.On() work as expected. However, everything inside the ikisocket.New()
function gets called only after the connection is closed.

For example:

  • I start a websocket connection from my client -> "fired connect 1" -> "fired connect 2"
  • I send a message from my client -> "fired: message: test message"
  • I disconnenct from my client -> "fired close: userid" -> "fired main callback inside ikisocket.New()" (which I added for debugging)

Also, the callbacks defined for kws.OnConnect and kws.OnMessage do not fire in the example (probably because they are also part of the ikisocket.New() callback.

Any idea on why the ikisocket.New() does not behave properly? Do you experience the same behavior?

Upgrade to support Fiber V2

Hello,

Since Fiber is improving and upgrading his project I've taken this opportunity to update also ikisocket.

This project was built as a solution to solve my problem with standard WebSockets management provided by Fiber, so I decided to create a more "extended" way of working with this kind of connection. More details here, in a post written months ago.

Upgrading this wrapper I had the opportunity to refactor and fix bugs (thank you @sebastianbuechler) trying to provide the same quality experience that Fiber provides.

That said, that's there is the changelog:

  • All the events are now totally supported by ikisocket.On function.
  • In-Callback events (OnMessage, OnConnect, OnDisconnect) are now deprecated and will be removed later.
  • There is no versioning support, this means that I will try to support only the currently active version alongside Fiber
  • Added Params(), Query(), Cookies() wrapped function, easily accessible from kws.Params(), kws.Query() and kws.Cookies()

Please, if you see any bug or especially if you have a suggestion, open an issue and I will try to reply to you ASAP!

Thank you!

Request for investigation | Server shuts down with exit code 2

Sorry for bugging you here again :(

Essentially, I find that if I run the server locally, and I continuously connect and disconnect and use it for a decent amount of time with two clients disconnecting and connecting over and over again with multiple connections to the server, there is a problem where it shuts down with this message let's say after like 10 minutes of all of it working.

exit status 2

I am not sure that this happens in my digital ocean hosted version but locally, and my bet is that it has to do with go routines not being cleaned up on socket disconnections and reaching 1000 go routines. Here is the stack trace.

This is long, but just want to make sure I am verbose enough as I don't understand the stack trace in the terminal:

`bufio.(*Reader).fill(0x140004c8900)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:106 +0x100
bufio.(*Reader).Peek(0x140004c8900, 0x2)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:144 +0x64
github.com/fasthttp/websocket.(*Conn).read(0x140006a0c60, 0x1027a8744?)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:371 +0x2c
github.com/fasthttp/websocket.(*Conn).advanceFrame(0x140006a0c60)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:809 +0x68
github.com/fasthttp/websocket.(*Conn).NextReader(0x140006a0c60)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:1009 +0xb0
github.com/fasthttp/websocket.(*Conn).ReadMessage(0x1400028bf78?)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:1093 +0x20
github.com/antoniodipinto/ikisocket.(*Websocket).read(0x140006ae3f0, {0x102ae9330, 0x1400013c740})
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:526 +0x130
created by github.com/antoniodipinto/ikisocket.(*Websocket).run
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:506 +0x134

goroutine 1939 [select]:
github.com/antoniodipinto/ikisocket.(*Websocket).pong(0x140006ae460, {0x102ae9330, 0x1400013c800})
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:451 +0xe0
created by github.com/antoniodipinto/ikisocket.(*Websocket).run
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:505 +0xc4

goroutine 1292 [select]:
github.com/antoniodipinto/ikisocket.(*Websocket).send(0x140005b81c0, {0x102ae9330, 0x140006b41c0})
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:472 +0x90
created by github.com/antoniodipinto/ikisocket.(*Websocket).run
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:507 +0x1a4

goroutine 1294 [select]:
github.com/antoniodipinto/ikisocket.(*Websocket).pong(0x140005b8230, {0x102ae9330, 0x140006b42c0})
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:451 +0xe0
created by github.com/antoniodipinto/ikisocket.(*Websocket).run
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:505 +0xc4

goroutine 291 [IO wait]:
internal/poll.runtime_pollWait(0x129d407a8, 0x72)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/runtime/netpoll.go:302 +0xa4
internal/poll.(*pollDesc).wait(0x1400027a280?, 0x14000399000?, 0x0)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_poll_runtime.go:83 +0x2c
internal/poll.(*pollDesc).waitRead(...)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_poll_runtime.go:88
internal/poll.(*FD).Read(0x1400027a280, {0x14000399000, 0x1000, 0x1000})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_unix.go:167 +0x1e4
net.(*netFD).Read(0x1400027a280, {0x14000399000?, 0x140000c7bf8?, 0x1029a8d20?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/net/fd_posix.go:55 +0x2c
net.(*conn).Read(0x14000110038, {0x14000399000?, 0x140000c7c18?, 0x1029a1024?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/net/net.go:183 +0x38
bufio.(*Reader).fill(0x140000b1020)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:106 +0x100
bufio.(*Reader).Peek(0x140000b1020, 0x1)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:144 +0x64
github.com/valyala/fasthttp.(*Server).serveConn(0x140000c06c0, {0x102ae9cf0?, 0x14000110038})
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2125 +0x4a8
github.com/valyala/fasthttp.(*workerPool).workerFunc(0x140000bac80, 0x1400051c160)
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:224 +0x70
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:196 +0x3c
created by github.com/valyala/fasthttp.(*workerPool).getCh
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:195 +0x22c

goroutine 1928 [IO wait]:
internal/poll.runtime_pollWait(0x129d403e8, 0x72)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/runtime/netpoll.go:302 +0xa4
internal/poll.(*pollDesc).wait(0x14000506280?, 0x140003c7000?, 0x0)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_poll_runtime.go:83 +0x2c
internal/poll.(*pollDesc).waitRead(...)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_poll_runtime.go:88
internal/poll.(*FD).Read(0x14000506280, {0x140003c7000, 0x1000, 0x1000})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_unix.go:167 +0x1e4
net.(*netFD).Read(0x14000506280, {0x140003c7000?, 0x102f25d28?, 0x5d?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/net/fd_posix.go:55 +0x2c
net.(*conn).Read(0x14000010050, {0x140003c7000?, 0x129d404d8?, 0x0?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/net/net.go:183 +0x38
bufio.(*Reader).Read(0x1400031d5c0, {0x1400069bc00, 0x400, 0x14000602380?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:236 +0x1e4
github.com/valyala/fasthttp.(*hijackConn).Read(0x0?, {0x1400069bc00?, 0x1400040b4f8?, 0x1029b1c88?})
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2493 +0x30
bufio.(*Reader).fill(0x140004c8540)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:106 +0x100
bufio.(*Reader).Peek(0x140004c8540, 0x2)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:144 +0x64
github.com/fasthttp/websocket.(*Conn).read(0x140006a09a0, 0x1027a8744?)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:371 +0x2c
github.com/fasthttp/websocket.(*Conn).advanceFrame(0x140006a09a0)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:809 +0x68
github.com/fasthttp/websocket.(*Conn).NextReader(0x140006a09a0)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:1009 +0xb0
github.com/fasthttp/websocket.(*Conn).ReadMessage(0x1400040b778?)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:1093 +0x20
github.com/antoniodipinto/ikisocket.(*Websocket).read(0x140006ae310, {0x102ae9330, 0x1400013c500})
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:526 +0x130
created by github.com/antoniodipinto/ikisocket.(*Websocket).run
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:506 +0x134

goroutine 1345 [IO wait]:
internal/poll.runtime_pollWait(0x129c8b8c8, 0x72)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/runtime/netpoll.go:302 +0xa4
internal/poll.(*pollDesc).wait(0x14000162580?, 0x14000460000?, 0x0)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_poll_runtime.go:83 +0x2c
internal/poll.(*pollDesc).waitRead(...)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_poll_runtime.go:88
internal/poll.(*FD).Read(0x14000162580, {0x14000460000, 0x1000, 0x1000})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_unix.go:167 +0x1e4
net.(*netFD).Read(0x14000162580, {0x14000460000?, 0x140000c3bf8?, 0x1029a8d20?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/net/fd_posix.go:55 +0x2c
net.(*conn).Read(0x14000426080, {0x14000460000?, 0x140000c3c18?, 0x1029a1024?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/net/net.go:183 +0x38
bufio.(*Reader).fill(0x1400030f980)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:106 +0x100
bufio.(*Reader).Peek(0x1400030f980, 0x1)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:144 +0x64
github.com/valyala/fasthttp.(*Server).serveConn(0x140000c06c0, {0x102ae9cf0?, 0x14000426080})
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2125 +0x4a8
github.com/valyala/fasthttp.(*workerPool).workerFunc(0x140000bac80, 0x1400044e100)
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:224 +0x70
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:196 +0x3c
created by github.com/valyala/fasthttp.(*workerPool).getCh
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:195 +0x22c

goroutine 1963 [chan receive]:
github.com/antoniodipinto/ikisocket.(*Websocket).run(0x140001202a0)
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:509 +0x1b4
github.com/antoniodipinto/ikisocket.New.func1(0x140002f2750)
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:272 +0x2d0
github.com/gofiber/websocket/v2.New.func2.4(0x102ae9be8?)
/Users/arjun.patel/go/pkg/mod/github.com/gofiber/websocket/[email protected]/websocket.go:109 +0x80
github.com/fasthttp/websocket.(*FastHTTPUpgrader).Upgrade.func1({0x102ae9be8, 0x140002f2840})
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/server_fasthttp.go:201 +0x164
github.com/valyala/fasthttp.hijackConnHandler(0xb0?, {0x102ae7008?, 0x1400012b5c0}, {0x102ae9cf0, 0x140000100c0}, 0x140000c06c0, 0x14000618400)
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2448 +0x60
created by github.com/valyala/fasthttp.(*Server).serveConn
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2403 +0x15e8

goroutine 1922 [chan receive]:
github.com/antoniodipinto/ikisocket.(*Websocket).run(0x140006ae2a0)
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:509 +0x1b4
github.com/antoniodipinto/ikisocket.New.func1(0x140002ddf50)
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:272 +0x2d0
github.com/gofiber/websocket/v2.New.func2.4(0x102ae9be8?)
/Users/arjun.patel/go/pkg/mod/github.com/gofiber/websocket/[email protected]/websocket.go:109 +0x80
github.com/fasthttp/websocket.(*FastHTTPUpgrader).Upgrade.func1({0x102ae9be8, 0x140003a75c0})
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/server_fasthttp.go:201 +0x164
github.com/valyala/fasthttp.hijackConnHandler(0x0?, {0x102ae7008?, 0x140006a4060}, {0x102ae9cf0, 0x14000010020}, 0x140000c06c0, 0x1400013c2c0)
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2448 +0x60
created by github.com/valyala/fasthttp.(*Server).serveConn
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2403 +0x15e8

goroutine 1926 [chan receive]:
github.com/antoniodipinto/ikisocket.(*Websocket).run(0x140006ae310)
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:509 +0x1b4
github.com/antoniodipinto/ikisocket.New.func1(0x14000302f30)
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:272 +0x2d0
github.com/gofiber/websocket/v2.New.func2.4(0x102ae9be8?)
/Users/arjun.patel/go/pkg/mod/github.com/gofiber/websocket/[email protected]/websocket.go:109 +0x80
github.com/fasthttp/websocket.(*FastHTTPUpgrader).Upgrade.func1({0x102ae9be8, 0x14000303020})
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/server_fasthttp.go:201 +0x164
github.com/valyala/fasthttp.hijackConnHandler(0x80?, {0x102ae7008?, 0x1400031d5c0}, {0x102ae9cf0, 0x14000010050}, 0x140000c06c0, 0x1400013c400)
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2448 +0x60
created by github.com/valyala/fasthttp.(*Server).serveConn
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2403 +0x15e8

goroutine 1792 [IO wait]:
internal/poll.runtime_pollWait(0x129d405c8, 0x72)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/runtime/netpoll.go:302 +0xa4
internal/poll.(*pollDesc).wait(0x14000506000?, 0x140000bd000?, 0x0)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_poll_runtime.go:83 +0x2c
internal/poll.(*pollDesc).waitRead(...)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_poll_runtime.go:88
internal/poll.(*FD).Read(0x14000506000, {0x140000bd000, 0x1000, 0x1000})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/internal/poll/fd_unix.go:167 +0x1e4
net.(*netFD).Read(0x14000506000, {0x140000bd000?, 0x102f25878?, 0x10277a15d?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/net/fd_posix.go:55 +0x2c
net.(*conn).Read(0x14000010008, {0x140000bd000?, 0x102f25878?, 0x1400040dc5d?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/net/net.go:183 +0x38
bufio.(*Reader).Read(0x14000285260, {0x1400069b400, 0x400, 0x30000007d?})
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:236 +0x1e4
github.com/valyala/fasthttp.(*hijackConn).Read(0x1400040dcc8?, {0x1400069b400?, 0x1308?, 0x102ab8340?})
/Users/arjun.patel/go/pkg/mod/github.com/valyala/[email protected]/server.go:2493 +0x30
bufio.(*Reader).fill(0x140004c8180)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:106 +0x100
bufio.(*Reader).Peek(0x140004c8180, 0x2)
/opt/homebrew/Cellar/go/1.18.5/libexec/src/bufio/bufio.go:144 +0x64
github.com/fasthttp/websocket.(*Conn).read(0x140006a06e0, 0x1027a8744?)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:371 +0x2c
github.com/fasthttp/websocket.(*Conn).advanceFrame(0x140006a06e0)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:809 +0x68
github.com/fasthttp/websocket.(*Conn).NextReader(0x140006a06e0)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:1009 +0xb0
github.com/fasthttp/websocket.(*Conn).ReadMessage(0x1400040df78?)
/Users/arjun.patel/go/pkg/mod/github.com/fasthttp/[email protected]/conn.go:1093 +0x20
github.com/antoniodipinto/ikisocket.(*Websocket).read(0x140006ae230, {0x102ae9330, 0x1400013c240})
/Users/arjun.patel/go/pkg/mod/github.com/antoniodipinto/[email protected]/ikisocket.go:526 +0x130`

Environments: this happens running with go run main.go and in a docker container.

Race condition for pool, listeners and kws

go run -race is reporting data races in your implementation. The pool and listeners maps should each have a sync.RWMutex. Furthermore, I would place RWMutex in Websocket struct and lock it, before changing any of the fields.

You could also write something like

type Websocket struct {
        sync.RWMutex
	// The Fiber.Websocket connection
	ws *websocket.Conn
	...
}

...

kws.Lock()
...
kws.Unlock()

Please Help - High CPU Usage

Sorry to keep bugging you for such a great package and some great work for an open source package @antoniodipinto

For some reason, there are spikes and plateaus in CPU usage.

Below is the digitalocean app platform insights. I have only one user connection, and there seems to be spikes and then just stays there. Memory is fine and stable. This is when there are websocket connections from one or two clients, but maybe there is no cleanup of some loop?

Screen Shot 2022-09-12 at 1 24 06 PM

image

BUG : Inconsistent Message Sending

Sometimes the client gets the full marshalled json, but sometimes, the client gets a JWT token starting with "ey..."

Any ides why? I know that for sure I am not sending a jwt token back. There seems to be some sort of race condition on the EmitTo.

when it does NOT work:
"eyJldmVudCI6InN0YXJ0ZWQgc3BlYWtpbmciLCJkYXRhIjp7Im1vcmUgaW5mb3JtYXRpb24iOiIiLCJ0ZXN0IjoiIGFzZGZhZHNmIn0sImZyb21fdXNlcl9pZCI6ImFudGhvbnkifQ=="

when it does work, I get the full json as expected
{ "event": "someone_joined", "data": [ "arjun" ], "from_user_id": "arjun" }

sending back to the browser

firstly this is a very good idea

i had a look through, but couldn't understand how to emit a message back to the client from server, the reading from client i understand, can you please explain it to me

thank you so much

(Question) custom events

Can i send custom events from websocket (frontend)? Or should i use socket.io?

may be is a noob question, but if i do

socket.send("string")
In my frontend, how the backend will know what specific string event is?

Or should i use a json, (as a string)?

If it's a json, what property indicates the event and the message?

Thanks, looks like a great library

Unexpected event-handler invoking

Describe the bug
Firstly I want to say thx for your awesome work!
My issue is that: in the same code base, I write 2 socket servers for different purposes. From wscat client, I connect to server A and then disconnect it and both disconnect event-handlers of 2 servers got invoked.

To Reproduce
Steps to reproduce the behavior:

  1. Codes

main.go

package main

func main() {
	s1 := CustomerServer{}
	go func() {
		s1.ListenAndServe(":5001")
	}()

	s2 := ProductServer{}
	go func() {
		s2.ListenAndServe(":5002")
	}()

	select {}
}

customer_server.go

package main

import (
	"log"

	"github.com/antoniodipinto/ikisocket"
	"github.com/gofiber/fiber/v2"
)

type CustomerServer struct{}

func (s CustomerServer) ListenAndServe(addr string) error {
	app := fiber.New()

	app.Get("/customer/:id", ikisocket.New(custHandleNewConn))

	ikisocket.On(ikisocket.EventDisconnect, custHandleDisconnect)

	return app.Listen(addr)
}

func custHandleNewConn(kws *ikisocket.Websocket) {
	log.Printf("[Customer Server] got new connection! %#v, %#v\n", kws.GetUUID(), kws.Params("id"))
	kws.SetAttribute("test_id", kws.Params("id"))
}

func custHandleDisconnect(ep *ikisocket.EventPayload) {
	log.Printf("[Customer Server] disconnect from %#v\n", ep.SocketAttributes["test_id"])
}

product_server.go

package main

import (
	"log"

	"github.com/antoniodipinto/ikisocket"
	"github.com/gofiber/fiber/v2"
)

type ProductServer struct{}

func (s ProductServer) ListenAndServe(addr string) error {
	app := fiber.New()

	app.Get("/product/:id", ikisocket.New(productHandleNewConn))

	ikisocket.On(ikisocket.EventDisconnect, productHandleDisconnect)

	return app.Listen(addr)
}

func productHandleNewConn(kws *ikisocket.Websocket) {
	log.Printf("[Product Server] got new connection! %#v, %#v\n", kws.GetUUID(), kws.Params("id"))
	kws.SetAttribute("test_id", kws.Params("id"))
}

func productHandleDisconnect(ep *ikisocket.EventPayload) {
	log.Printf("[Product Server] disconnect from %#v\n", ep.SocketAttributes["test_id"])
}
  1. Attach log

starting servers

โžœ  chat-server go run .

 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” 
 โ”‚                   Fiber v2.37.1                   โ”‚ 
 โ”‚               http://127.0.0.1:5002               โ”‚ 
 โ”‚       (bound on host 0.0.0.0 and port 5002)       โ”‚ 
 โ”‚                                                   โ”‚ 
 โ”‚ Handlers ............. 2  Processes ........... 1 โ”‚ 
 โ”‚ Prefork ....... Disabled  PID ........... 1869661 โ”‚ 
 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 


 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” 
 โ”‚                   Fiber v2.37.1                   โ”‚ 
 โ”‚               http://127.0.0.1:5001               โ”‚ 
 โ”‚       (bound on host 0.0.0.0 and port 5001)       โ”‚ 
 โ”‚                                                   โ”‚ 
 โ”‚ Handlers ............. 2  Processes ........... 1 โ”‚ 
 โ”‚ Prefork ....... Disabled  PID ........... 1869661 โ”‚ 
 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 

2022/09/19 12:15:05 [Customer Server] got new connection! "ONjHvu2ivwdHqiqJn55yTPMAMEEOyPVJ9UV9GwfeGxSQSVIA6mNAT8z31h35Pe0ZnjmGvGAMVFFRObxB0g4Gy0tZHdv8hqChwTTS", "cust_id_1"
2022/09/19 12:15:08 [Product Server] disconnect from "cust_id_1"
2022/09/19 12:15:08 [Customer Server] disconnect from **"cust_id_1"**

wscat client-side

โžœ  ~ wscat -c ws://localhost:5001/customer/cust_id_1
Connected (press CTRL+C to quit)
> % 
  1. Define expected behavior

Only event-handler of relevant server will be called.

(Question) Is there a way to use this library to open a new connection to another server?

Is your feature request related to a problem? Please describe.
I'm trying to use this library to simplify setting up a proxy. To do that on 'EventConnect' I need to open a new connection. Then I can just replicate messages from each source back to the other by setting the UUID as a stored value on them.

Describe the solution you'd like
Just wondering if there is a way to programmatically create a client websocket to a specific domain.

EmitTo not working?

Describe the bug
It seems only Broadcast() and Emit() are working but only for ikisocket.EventMessage. But when using EmitTo() there is nothing.

To Reproduce
Steps to reproduce the behavior:

  1. Server code:
package main

import (
	"fmt"

	"github.com/antoniodipinto/ikisocket"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/websocket/v2"
)

func main() {
	app := fiber.New()

	app.Use("/ws", func(c *fiber.Ctx) error {
		if websocket.IsWebSocketUpgrade(c) {
			c.Locals("allowed", true)
			return c.Next()
		}
		return fiber.ErrUpgradeRequired
	})

	ikisocket.On(ikisocket.EventConnect, func(ep *ikisocket.EventPayload) {
		fmt.Printf("Client %s connected\n", ep.Kws.GetUUID())
		ep.Kws.Emit([]byte("Hello from server"))
	})

	ikisocket.On(ikisocket.EventDisconnect, func(ep *ikisocket.EventPayload) {
		fmt.Printf("Client %s disconnected\n", ep.Kws.GetUUID())
		ikisocket.Broadcast([]byte("Client disconnected"))
	})

	ikisocket.On("orders", func(ep *ikisocket.EventPayload) {
		fmt.Printf("Client %s sent orders\n", ep.Kws.GetUUID())
		ikisocket.EmitTo(ikisocket.EventMessage, []byte("hey there"))
	})

	app.Post("/orders", func(c *fiber.Ctx) error {
		ikisocket.EmitTo("orders", c.Body(), ikisocket.TextMessage)
		ikisocket.Fire("orders", []byte("order added"))
		return c.SendString("orders")
	})

	app.Get("/ws", ikisocket.New(func(kws *ikisocket.Websocket) {
		kws.Broadcast([]byte("Client connected"), true, ikisocket.TextMessage)
		kws.Emit([]byte("Welcome to the websocket"))
		kws.Emit([]byte("You are the best"))
		kws.EmitTo("orders", []byte("hey there"))
		kws.EmitTo(ikisocket.EventMessage, []byte("hey there"))
	}))

	app.Listen(":8080")
}

client code:

import WebSocket from "ws";

let ws = new WebSocket("ws://localhost:8080/ws");

ws.on("message", (data) => {
  console.log("message");
  data = Buffer.from(data).toString();
  console.log(data);
});

ws.on("error", (error) => {
  console.log(error);
});

ws.on("close", (code, reason) => {
  console.log("close");
  console.log(code, Buffer.from(reason).toString());
});

ws.on("orders", (data) => {
  console.log("orders");
  data = Buffer.from(data).toString();
  console.log(data);
});
  1. From the client I get only the data from predefined event that are fired from the server by Emit() or Broadcast(). Not getting anything from EmitTo()

Expected behavior
EmitTo() should work for predefined events as well as custom events.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.