Skip to content

Commit

Permalink
fix: handle sse events correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
HamoonZamiri committed Aug 30, 2024
1 parent 253d57c commit b3e9f71
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 67 deletions.
2 changes: 1 addition & 1 deletion backend/routes/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func AddRoutes(

CorsChain := middleware.CreateChain(middleware.Logging, c.Handler)
AuthChain := middleware.CreateChain(middleware.Logging, c.Handler, middleware.AuthenticatedOnly)
QueryTokenAuthChain := middleware.CreateChain(middleware.QueryTokenAuth)
QueryTokenAuthChain := middleware.CreateChain(c.Handler, middleware.QueryTokenAuth)

mux.Handle("GET /health", CorsChain(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Write([]byte("Hello\n"))
Expand Down
12 changes: 1 addition & 11 deletions backend/utils/events/sse.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"log/slog"
"net/http"
"time"

"github.com/google/uuid"
)
Expand Down Expand Up @@ -48,15 +47,10 @@ func (em *EventManager) SSEHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:5173")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Expose-Headers", "Content-Type")
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")

w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("X-Accel-Buffering", "no")

conn := newSSEConn(w, userId)
em.SubscribeToUserEvents(conn.userId, conn)
Expand All @@ -73,10 +67,6 @@ func (em *EventManager) SSEHandler(w http.ResponseWriter, r *http.Request) {
}
w.(http.Flusher).Flush()
}
case <-time.After(10 * time.Second):
// Send a keep-alive message
fmt.Fprintf(w, ": keep-alive\n\n")
w.(http.Flusher).Flush()
case <-r.Context().Done():
return
}
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/components/pages/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import ModalForm from "@/components/ModalForm.vue";
import CreateGoalCategoryForm from "@/components/goals/forms/CreateGoalCategoryForm.vue";
import CreateCategoryButton from "@/components/goals/buttons/CreateCategoryButton.vue";
import goalState from "@/state/goals";
import useWebSocket from "@/hooks/useWebSocket";
import { WS_BASE } from "@/utils/constants";
import authState from "@/state/auth";
import { useSSE } from "@/hooks/events/useSse";
// State
const error = ref<ErrorResponse | null>(null);
const isLoading = ref<boolean>(true);
const { connect } = useWebSocket(
`ws://localhost:8080/api/ws?token=${authState.getUser()?.access_token}`,
const { connect } = useSSE(
`http://localhost:8080/api/events?token=${authState.getUser()?.access_token}`,
);
onMounted(async () => {
Expand Down
43 changes: 43 additions & 0 deletions frontend/src/hooks/events/useSse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import goalState from "@/state/goals";
import { events } from "@/utils/constants";
import { Schemas } from "@/utils/schemas";
import { onUnmounted, ref } from "vue";

export function useSSE(url: string) {
const eventSource = ref<EventSource | null>(null);

const connect = () => {
if (eventSource.value) {
return;
}

const es = new EventSource(url);
es.onopen = () => {
console.log("connected");
console.log("readystate:", es.readyState);
};
es.onerror = (event) => {
console.error("error", event);
};

es.addEventListener(events.DEFAULT_GOAL_CREATED, (event) => {
const json = JSON.parse(event.data);
const parsedData = Schemas.GoalSchema.parse(json);
goalState.addGoal(parsedData.category_id, parsedData);
});

eventSource.value = es;
};

onUnmounted(() => {
if (eventSource.value) {
eventSource.value.close();
}
eventSource.value = null;
});

return {
eventSource,
connect,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@ const UserEventSchema = createEventSchema(Schemas.UserSchema);
const GoalEventSchema = createEventSchema(Schemas.GoalSchema);
const GoalCategoryEventSchema = createEventSchema(Schemas.GoalCategorySchema);

const EventSchemas = {
export const EventSchemas = {
[events.USER_CREATED]: UserEventSchema,
[events.GOAL_CREATED]: GoalEventSchema,
[events.GOAL_CATEGORY_CREATED]: GoalCategoryEventSchema,
[events.USER_UPDATED]: UserEventSchema,
[events.DEFAULT_GOAL_CREATED]: GoalEventSchema,
} as const;

export function handleDefaultGoalCreated(
event: z.infer<(typeof EventSchemas)[typeof events.DEFAULT_GOAL_CREATED]>,
) {
goalState.addGoal(event.data.category_id, event.data);
}
export default function useWebSocket(url: string) {
const websocket = ref<WebSocket | null>(null);

Expand Down Expand Up @@ -54,17 +59,6 @@ export default function useWebSocket(url: string) {
return { connect };
}

function handleGoalCategoryCreated(
event: z.infer<(typeof EventSchemas)[typeof events.GOAL_CATEGORY_CREATED]>,
) {
return;
}

function handleDefaultGoalCreated(
event: z.infer<(typeof EventSchemas)[typeof events.DEFAULT_GOAL_CREATED]>,
) {
goalState.addGoal(event.data.category_id, event.data);
}
function handleEvent(event: MessageEvent) {
const json = JSON.parse(event.data);
const eventType = json.event_type as string;
Expand Down
39 changes: 0 additions & 39 deletions frontend/src/hooks/useSse.ts

This file was deleted.

0 comments on commit b3e9f71

Please sign in to comment.