Last updated: February 5, 2025

<span aria-hidden="true" id="real-time-file-processing-with-deno-and-websockets"></span>

# Real-time file processing with Deno and Websockets

![Kevin van Zonneveld](/assets/images/teammates/avatar-kvz-4.jpg?dpl=dpl_3fBRD5jmFtSDABLXGJJyXU1nVXf8)

**Kevin van Zonneveld**

Co-founder · Amsterdam, The Netherlands · Show bio

[](https://x.com/kvz)[](https://github.com/kvz)

With the rise of real-time applications, developers are constantly seeking efficient ways to handle live data streams and process files on the fly. Deno, a modern runtime for JavaScript and TypeScript, offers robust WebSocket support and enhanced security features that make it an excellent choice for building secure, real-time file processing systems.

In this DevTip, we'll explore how to leverage Deno's WebSocket capabilities and its secure permissions model to implement a real-time WebSocket server. This pattern can serve as a foundation for real-time file processing tasks—such as monitoring and processing file data—as part of a broader application ecosystem.

<span aria-hidden="true" id="why-deno"></span>

## Why Deno?

Deno provides a secure runtime that includes TypeScript support, an integrated permissions system, and a sandboxed environment. These features help ensure that operations, including file processing tasks, are executed safely without exposing unnecessary system resources. Unlike Node.js, Deno focuses on security and simplicity, giving you more control over network and file system access.

<span aria-hidden="true" id="setting-up-a-websocket-server"></span>

## Setting up a websocket server

Create a new file called `server.ts` and add the following code:

```typescript
Deno.serve((req) => {
  if (req.headers.get('upgrade') !== 'websocket') {
    return new Response(null, { status: 501 })
  }

  const { socket, response } = Deno.upgradeWebSocket(req)

  socket.addEventListener('open', () => {
    console.log('A client connected!')
  })

  socket.addEventListener('message', (event) => {
    if (event.data === 'ping') {
      // In a real application, you might trigger file processing here
      socket.send('pong')
    }
  })

  socket.addEventListener('error', (event) => {
    console.error('WebSocket error:', event)
  })

  socket.addEventListener('close', () => {
    console.log('A client disconnected')
  })

  return response
})

```

<span aria-hidden="true" id="running-the-server"></span>

### Running the server

To run the server, execute:

```bash
deno run --allow-net server.ts

```

<span aria-hidden="true" id="understanding-the-websocket-lifecycle"></span>

## Understanding the websocket lifecycle

WebSocket connections transition through several states:

1. **CONNECTING** (0): The initial state while establishing the connection.
2. **OPEN** (1): The connection is active and ready for data transfer.
3. **CLOSING** (2): The connection is in the process of closing.
4. **CLOSED** (3): The connection has been terminated.

For example, you can check if a socket is ready before sending a message:

```typescript
function isSocketReady(socket: WebSocket): boolean {
  return socket.readyState === WebSocket.OPEN
}

socket.onmessage = (event) => {
  if (!isSocketReady(socket)) {
    return
  }
  // Handle message
}

```

<span aria-hidden="true" id="client-implementation"></span>

## Client implementation

Below is a streamlined client example to test the server:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>WebSocket Test</title>
  </head>
  <body>
    <script>
      const ws = new WebSocket('ws://localhost:8000')
      ws.onopen = () => {
        console.log('Connected to the server')
        ws.send('ping')
      }
      ws.onmessage = (event) => {
        console.log('Received:', event.data)
      }
      ws.onerror = (error) => {
        console.error('WebSocket error:', error)
      }
      ws.onclose = () => {
        console.log('Disconnected from the server')
      }
    </script>
  </body>
</html>

```

<span aria-hidden="true" id="security-best-practices"></span>

## Security best practices

When building real-time applications, especially those involving file processing, consider these security measures:

### 1. Input validation

Ensure incoming data is correctly formatted to avoid processing unexpected inputs.

```typescript
function validateMessage(data: unknown): boolean {
  if (typeof data !== 'string') {
    return false
  }

  try {
    const message = JSON.parse(data)
    return typeof message === 'object' && message !== null && typeof message.type === 'string'
  } catch {
    return false
  }
}

```

### 2. Rate limiting

Integrate a rate limiter to prevent abuse and ensure system stability.

```typescript
class RateLimiter {
  private requests = new Map<string, number[]>()
  private readonly limit: number
  private readonly window: number

  constructor(limit = 100, window = 60000) {
    this.limit = limit
    this.window = window
  }

  isAllowed(clientId: string): boolean {
    const now = Date.now()
    const timestamps = this.requests.get(clientId) || []
    const recent = timestamps.filter((time) => now - time < this.window)

    if (recent.length >= this.limit) {
      return false
    }

    recent.push(now)
    this.requests.set(clientId, recent)
    return true
  }
}

```

### 3. Message size limits

Constrain message sizes to mitigate the risk of denial-of-service attacks.

```typescript
const MAX_MESSAGE_SIZE = 1024 * 1024 // 1MB

socket.addEventListener('message', (event) => {
  if (typeof event.data === 'string' && event.data.length > MAX_MESSAGE_SIZE) {
    socket.send(
      JSON.stringify({
        type: 'error',
        message: 'Message size exceeds limit',
      }),
    )
    return
  }
  // Process message
})

```

<span aria-hidden="true" id="conclusion"></span>

## Conclusion

Deno's built-in WebSocket support and strong security model make it a powerful tool for developing real-time applications, including those that process files dynamically. By applying the best practices outlined in this guide, you can build secure and efficient systems capable of handling real-time data and file operations.

At Transloadit, we recognize the value of secure, real-time communication. Explore our[File Filtering](/docs/robots/file-filter.md) service to see how advanced file handling can complement your real-time applications.

\#deno#web-sockets#real-time#file-processing

### 👩‍💻 Join 20k+ developers

Sign up for our [monthly newsletter](/newsletters.md) to receive direct links to 3 exclusive tech — and 2 product updates. No less, no more.

Your email:

Get access

## File uploading and encoding. Made simple.

Transloadit streamlines file handling for developers, trusted by brands like Coursera and The New York Times. We’re known for a reliable API, top-notch support, and a strong commitment to open source, with projects like [Uppy⁠](https://uppy.io) and [Tus⁠](https://tus.io) setting standards in file processing.

[Sign up](/c/)[Book a Demo](https://survey.typeform.com/to/kRg47Xi5)

No credit card needed · 5 GB included in the free plan

Cancel anytime
