Socket Programming with Python and PubNub

1,483
PubNub
Build real-time apps quickly and scale them globally.

Sockets (aka socket programming) enable programs to send and receive data, bi-directionally, at any given moment. This tutorial walks through how you can send data from device-to-device, client-to-server, and vice versa using socket programming in Python.

Why use sockets to send data?

Internet-connected applications that need to operate in realtime greatly benefit from the implementation of sockets in their networking code. Some examples of apps that use socket programming are:

Python, unlike JavaScript, is a language that executes synchronously. This is why asyncio was developed – to make Python more robust, particularly for the nature of socket programming.

With streaming sockets, data can be sent or received at any time. In case your Python program is in the middle of executing some code, other threads can handle the new socket data. Libraries like asyncio implement multiple threads, so your Python program can work in an asynchronous fashion.

Python Socket Programming Tutorial

Natively, Python provides a socket class so developers can easily implement socket objects in their source code. To use a socket object in your program, start off by importing the socket library. No need to install it with a package manager, it comes out of the box with Python.

import socket

Now we can create socket objects in our code.

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

This code creates a socket object that we are storing in the “sock” variable. The constructor is provided a family and type parameter respectively. The family parameter is set to the default value, which is the Address Format Internet.

The type parameter is set to Socket Stream, also the default which enables “sequenced, reliable, two-way, connection-based byte streams” over TCP1.

Once we have an initialized socket object, we can use some methods to open a connection, send data, receive data, and finally close the connection.

## Connect to an IP with Port, could be a URL
sock.connect(('0.0.0.0', 8080))

## Send some data, this method can be called multiple times
sock.send("Twenty-five bytes to send")

## Receive up to 4096 bytes from a peer
sock.recv(4096)

## Close the socket connection, no more data transmission
sock.close()

Python Socket Server

Now that we know a few methods for transmitting bytes, let’s create a client and server program with Python.

import socket

serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

serv.bind(('0.0.0.0', 8080))
serv.listen(5)

while True:
    conn, addr = serv.accept()
    from_client = ''

    while True:
        data = conn.recv(4096)
        if not data: break
        from_client += data
        print from_client

        conn.send("I am SERVER\n")

    conn.close()
    print 'client disconnected'

This code makes a socket object, and binds it to localhost’s port 8080 as a socket server. When clients connect to this address with a socket connection, the server listens for data, and stores it in the “data” variable.

Next, the program logs the client data using “print,” and then sends a string to the client: I am SERVER.

Let’s take a look at client code that would interact with this server program.

Python Socket Client

Here is the client socket demo code.

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('0.0.0.0', 8080))

client.send("I am CLIENT\n")

from_server = client.recv(4096)

client.close()

print from_server

This client opens up a socket connection with the server, but only if the server program is currently running. To test this out yourself, you will need to use 2 terminal windows at the same time.

Next, the client sends some data to the server: I am CLIENT

Then the client receives some data it anticipates from the server.

Done! You can now get started streaming data between clients and servers using some basic Python network programming.

How Do You Send Data Between Clients?

Sending data between 2 or more client devices over the internet is tricky. Due to protections implemented by network security, not all devices connected to the world wide web have a publicly accessible internet protocol (IP) address.

This means that the Python code that we implemented will not be 100% reliable for sending peer-to-peer data in our realtime app. How do we achieve reliability and speed when transmitting peer-to-peer data?

This can be accomplished using a server in the middle. Client devices using the internet can connect to a server with a public IP address (or a website domain). Then, this broker in the middle can pass messages routed to 1 or many clients.

PubNub does this best with the Pub/Sub API. It is fast, reliable, secure, and easy to implement on any client device. Whether you have a Python server, a JavaScript website, or anything in between, you can use PubNub to send data to anyone in under 250ms.

With One-to-Many, One-to-One, or Many-to-Many, PubNub scales automatically to support any application load. Using the API opens up an instant, always-on connection between all clients that have the Pub/Sub API keys. This accomplishes the same objectives as a socket connection.

PubNub and Python with an SSL Connection

Here is an example of peer-to-peer data that is sent with PubNub, on a single channel, with SSL. You can think of this like sending data over a TCP socket. When you sign up for a free PubNub account, you can use a practically infinite number of channels to send messages in realtime. Before you try the code, be sure to make a free PubNub account.

Client 1

from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNStatusCategory
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
import time
import os

pnconfig = PNConfiguration()

pnconfig.publish_key = 'your pubnub publish key here'
pnconfig.subscribe_key = 'your pubnub subscribe key here'
pnconfig.ssl = True

pubnub = PubNub(pnconfig)

def my_publish_callback(envelope, status):
    # Check whether request successfully completed or not
    if not status.is_error():
        pass

class MySubscribeCallback(SubscribeCallback):
    def presence(self, pubnub, presence):
        pass
    def status(self, pubnub, status):
        pass
    def message(self, pubnub, message):
        print "from device 2: " + message.message

pubnub.add_listener(MySubscribeCallback())
pubnub.subscribe().channels("chan-1").execute()

## publish a message
while True:
    msg = raw_input("Input a message to publish: ")
    if msg == 'exit': os._exit(1)
    pubnub.publish().channel("chan-1").message(str(msg)).pn_async(my_publish_callback)

Client 2

Strings can be entered on the command line for these 2 client programs. Maximum message size for PubNub publishing is 32kb. Use 2 terminal windows to try out the code!


from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNStatusCategory
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
import time
import os

pnconfig = PNConfiguration()

pnconfig.publish_key = 'your pubnub publish key here'
pnconfig.subscribe_key = 'your pubnub subscribe key here'
pnconfig.ssl = True

pubnub = PubNub(pnconfig)

def my_publish_callback(envelope, status):
    # Check whether request successfully completed or not
    if not status.is_error():
        pass

class MySubscribeCallback(SubscribeCallback):
    def presence(self, pubnub, presence):
        pass
    def status(self, pubnub, status):
        pass
    def message(self, pubnub, message):
        print "from device 1: " + message.message

pubnub.add_listener(MySubscribeCallback())
pubnub.subscribe().channels("chan-1").execute()

## publish a message
while True:
    msg = raw_input("Input a message to publish: ")
    if msg == 'exit': os._exit(1)
    pubnub.publish().channel("chan-1").message(str(msg)).pn_async(my_publish_callback)

All of the code in this post is hosted on GitHub in the Python Socket Demo repository.

PubNub is entirely free up to 1 million messages per month. For more capability of the API, check out the PubNub Python v4 SDK documentation, or any of the other 75+ PubNub client SDKs.

PubNub
Build real-time apps quickly and scale them globally.
Tools mentioned in article
Open jobs at PubNub
Senior Fullstack Software Engineer (S...
Poland -
<p><strong>About PubNub</strong></p> <p>Join <a href="http://www.pubnub.com">PubNub</a>, a pioneer in revolutionizing real-time apps and games, powering thousands of companies, including DAZN, RingCentral, Adobe, and Docusign. Our platform powers real-time features in applications, enhancing virtual experiences with reliability, scalability, and security. Embrace flexibility with our remote-first approach, work from our beautiful Katowice office in the <a href="https://ktw.com.pl/">KTW building</a>, or a combination of both.&nbsp; We value a collaborative work environment tailored to your best work style.</p> <p><strong>About the Job </strong></p> <p>The Senior Software Engineer will work in the team tasked with designing, developing, and maintaining serverless (Functions, Events and Actions and Data Pipelines) solutions to support various projects within the organization. The team operates in an agile environment, collaborating closely with stakeholders from different departments to understand project requirements, iterate on solutions, and deliver high-quality outcomes within project timelines.The job will involve both front-end and back-end development, development of serverless functions runtimes, various aspects of DevOps and DevTest, performance analysis and tuning and a lot of high loaded systems.</p> <p><strong>Responsibilities:</strong></p> <ul> <li>Design and build PubNub’s Serverless Functions, Events &amp; Actions and Data Pipelines solutions.</li> <li>Champion adherence to the best practice of development methodologies across the entire team and help establish standards.</li> <li>Work collaboratively with other Engineering teams, Product Management, Marketing, Sales, and</li> <li>Customer Success to develop new features and create customer value.</li> <li>Build comprehensive DevOps into the SDLC architecture including, but not limited to: automated testing, continuous integration and delivery, and release management.</li> <li>Ensure a high level of test coverage for all code written, including unit and automated regression (smoke) tests, load and performance tests, etc</li> <li>Ensure that solutions meet requirements outlined in the design documentation.</li> </ul> <p><strong>About You</strong></p> <p>If you're a collaborative team player with excellent communication skills and a customer-centric perspective who is driven to cutting-edge technologies and languages, we want to connect with you. Bring your expertise to PubNub, where we value</p> <ul> <li>Bachelor's degree in Computer Science, Computer Engineering or related field required or equivalent professional experience</li> <li>7+ years experience with end-to-end design and development, and troubleshooting of high scale cloud services, and developing technical business solutions in general</li> <li>Experience with developing front-end web apps in React / Typescript as well as backend for front-end in Typescript</li> <li>Good command over javascript/ecmascript and understanding (or desire to learn) of javascript runtimes' internals</li> <li>Experience with developing in Kotlin or other jvm language(s)</li> <li>Experience with containerised applications using Docker or equivalent</li> <li>Broad programming language skills and experience. Strong Golang and/or Rust experience or desire to learn is highly beneficial.</li> <li>Experience with configuration as code paradigm (CI/CD pipelines,Terraform/Terragrunt) and automation/configuration management</li> <li>Experience with AWS EKS or other cloud-hosted Kubernetes clusters (EKS preferred)</li> <li>Past experience in public cloud deployments (AWS, Google Cloud Platform, Azure, Rackspace, SoftLayer, etc.).</li> <li>Experience with Kafka / Confluent ecosystem (Kafka Connect and Streams, Schema Registry)</li> <li>Experience with data serialization and schema evolution tools and development strategies, e.g.. Avro, JSON Schema, Protocol Buffers or&nbsp;equivalent</li> <li>Fluency in English&nbsp; (...Ale lokalnie mówimy też po Polsku :) )</li> </ul> <p><strong>Why PubNub</strong></p> <p>Be part of a vibrant team shaping real-time interactions in gaming while broadening your technical horizons in a diverse and forward-thinking environment. Choose PubNub, where collaboration and innovation intersect in a dynamic environment. Become part of a team that impacts not only what we do but also how we do it. All ideas are valued, promoted, and successes celebrated. Our product development is an open, collaborative effort, with local senior leadership and the ability to make key decisions quickly and efficiently. We support a flexible work culture, allowing for both remote work and in-person collaborations while offering a Competitive Salary (Monthly Range of PLN25,000 - PLN 30,000), Stock Options and other <a href="https://www.pubnub.com/company/careers/">Perks.&nbsp;</a></p> <p><em>PubNub is an Equal Employment Opportunity Employer, committed to an inclusive workplace where we do not discriminate based on </em><em>race, color, ancestry, religion, sex, national origin, sexual orientation, gender identity, age, marital or family status, disability, Veteran status, and any other status. We believe in Diversity and encourage any qualified individual to apply.&nbsp;</em></p> <p><em>A message to applicants applying to work in Poland. Factors affecting starting pay within this range may include geography, market, skills, education, training, experience, and other qualifications.&nbsp; The full salary range is also based on the successful candidate’s hiring location.&nbsp; The recruiter will provide additional information during the hiring process. Also note that this job supports only B2B Collaboration.&nbsp;</em></p>
Verified by
You may also like