Day 25: Nexios Event System
Learning Objectives
- Understand Nexios's event system fundamentals
- Implement event-driven patterns
- Work with WebSocket events
- Manage event listeners effectively
Event System Overview
Nexios provides a flexible event system that enables loosely coupled, event-driven architectures. The system is built around these core concepts:
- Basic event subscription and emission
- Event namespaces for organization
- Priority-based listeners
- One-time event handlers
- WebSocket integration
- Async event support
Basic Event Usage
python
from nexios import NexiosApp
app = NexiosApp()
@app.events.on("user.created")
async def handle_user_created(user):
print(f"User created: {user['name']}")
# Trigger the event
await app.events.emit("user.created", {"name": "Bob"})
Event Listeners
Basic Subscription
python
@app.events.on("data.received")
async def handle_data(data):
print(f"Processing data: {data}")
Removing Listeners
python
# Define handler
async def temporary_handler(data):
print(f"Processing data: {data}")
# Add handler
app.events.on("data.received", temporary_handler)
# Remove specific handler
app.events.off("data.received", temporary_handler)
# Remove all handlers for an event
app.events.off("data.received")
Priority Listeners
python
from nexios.events import EventPriority
# Different priority levels
app.events.on("data.received", handler1, priority=EventPriority.LOW)
app.events.on("data.received", handler2, priority=EventPriority.MEDIUM)
app.events.on("data.received", handler3, priority=EventPriority.HIGH)
One-time Listeners
python
@app.events.once('first.login')
async def first_login(user):
print(f"🎉 Welcome {user}")
await app.events.emit('first.login', 'Alice') # Fires
await app.events.emit('first.login', 'Alice') # Doesn't fire
Event Namespaces
python
# Create a namespace
ui_events = app.events.namespace('ui')
@ui_events.on('button.click') # Listens to 'ui:button.click'
async def handle_click(btn):
print(f"{btn} clicked!")
# Both work:
await ui_events.emit('button.click', 'submit')
await app.events.emit('ui:button.click', 'submit')
WebSocket Integration
Connection Events
python
@app.ws_route("/chat")
async def chat_handler(ws: WebSocket):
await ws.accept()
await app.events.emit("ws.connected", {"client": ws.client})
try:
while True:
message = await ws.receive_json()
await app.events.emit("chat.message", message)
except Exception as e:
await app.events.emit("ws.error", {"error": str(e)})
Notifications Example
python
@app.events.on("notification.created")
async def push_notification(notification):
await ChannelBox.group_send(
group_name="notifications",
payload=notification
)
Error Handling
python
@app.events.on("ws.error")
async def handle_errors(error):
logging.error(f"WebSocket failure: {error}")
# Alert monitoring systems
try:
# Your code here
...
except Exception as e:
await app.events.emit("ws.error", {"error": str(e)})
Complete Chat Application Example
python
@app.ws_route("/chat/{room}")
async def chat_room(ws: WebSocket):
room = ws.path_params["room"]
channel = Channel(websocket=ws)
await ChannelBox.add_channel_to_group(channel, f"chat_{room}")
try:
while True:
msg = await ws.receive_json()
await app.events.emit("room.message", {
"room": room,
"message": msg
})
finally:
await ChannelBox.remove_channel_from_group(channel, f"chat_{room}")
@app.events.on("room.message")
async def broadcast(msg):
await ChannelBox.group_send(
group_name=f"chat_{msg['room']}",
payload=msg
)
Best Practices
Event Naming:
- Use descriptive event names
- Follow a consistent naming pattern
- Use namespaces for organization
Error Handling:
- Always handle WebSocket exceptions
- Emit error events for centralized handling
- Log errors appropriately
WebSocket Integration:
- Use ChannelBox for group messaging
- Properly manage connections
- Clean up resources in finally blocks
Event Design:
- Keep events focused and single-purpose
- Document event payloads
- Consider using TypeScript for type safety
📝 Practice Exercise
Build a real-time chat application:
- Implement room-based chat using WebSockets
- Use events for message broadcasting
- Add error handling
- Implement user presence tracking
Create a notification system:
- Set up event-based notifications
- Implement priority-based handlers
- Add WebSocket push notifications
- Handle offline message queueing