Netty Frontend/Backend (What We Used in Our Project)
package com.corundumstudio.socketio.demo;
import com.corundumstudio.socketio.listener.*;
import java.util.HashSet;
import java.util.Set;
import com.corundumstudio.socketio.*;
public class MotorSocketSetup {
public static Set<String> userQueue = new HashSet<>();
public static void main(String[] args) throws InterruptedException {
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(9092);
final SocketIOServer server = new SocketIOServer(config);
// probably have to change `String.class` to `Integer.class` I'd check if ID is a integer or stinrg
server.addEventListener("checkUser", String.class, new DataListener<String>(){
@Override
public void onData(final SocketIOClient client, String userId, final AckRequest ackRequest){
boolean userExists = userQueue.contains(userId);
client.sendEvent("checkExist", userExists);
System.out.printf("User with id %s exists "+userId);
}
});
server.addConnectListener(new ConnectListener() {
@Override
public void onConnect(SocketIOClient client) {
String userId = client.getSessionId().toString();
userQueue.add(userId);
server.getBroadcastOperations().sendEvent("newUserJoined", "New user joined with ID: "+userId);
System.out.println("New user joined with ID: " + userId);
}
});
server.addEventListener("up", String.class, new DataListener<String>() {
@Override
public void onData(final SocketIOClient client, String data, final AckRequest ackRequest) {
// Run code to go up
System.out.println("going up");
}
});
server.addEventListener("left", String.class, new DataListener<String>() {
@Override
public void onData(final SocketIOClient client, String data, final AckRequest ackRequest) {
// run code to go left
System.out.println("going left");
}
});
server.addEventListener("right", String.class, new DataListener<String>() {
@Override
public void onData(final SocketIOClient client, String data, final AckRequest ackRequest) {
// run code to go right
System.out.println("going right");
}
});
server.addEventListener("down", String.class, new DataListener<String>() {
@Override
public void onData(final SocketIOClient client, String data, final AckRequest ackRequest) {
// run code to go down
System.out.println("going down");
}
});
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Demo Chat</title>
<link href="bootstrap.css" rel="stylesheet">
<style>
body {
padding:20px;
}
#console {
height: 400px;
overflow: auto;
}
.username-msg {color:orange;}
.connect-msg {color:green;}
.disconnect-msg {color:red;}
.send-msg {color:#888}
</style>
<script src="js/socket.io/socket.io.js"></script>
<script src="js/moment.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
var userName = 'user' + Math.floor((Math.random()*1000)+1);
var socket = io.connect('http://localhost:9092');
socket.on('connect', function() {
output('<span class="connect-msg">Client has connected to the server!</span>');
});
socket.on('senttodata', function(data) {
output('<span class="username-msg">' + data.userName + ':</span> ' + data.message);
});
socket.on('disconnect', function() {
output('<span class="disconnect-msg">The client has disconnected!</span>');
});
socket.on('newUserJoined', function(message) {
output('<span class="connect-msg">' + message + '</span>');
});
/* socket.on('queue', function(queue) { If I remember correctly we already have this, but just in case we decide to use it
const queueList = document.getElementById('userQueue');
queueList.innerHTML = 'Users in Queue: ' + queue.map(user => user.id)
});*/
//
var uid;
function checkUser(){
var userId = document.getElementById('userIdCheck').value; // creates a unique id number for each user
socket.emit('checkUser', userId); // sends a message to all already connected clients
var bool = true;
if (!userQueue.contains(userId)) {
bool = false;
}
var message = bool ? "User with ID " + userId + " exists." : "User with ID " + userId + " does not exist.";
output('<span class="username-msg">' + message + '</span>'); // what is shown in the output if the user exists
}
socket.on('checkExist', function(exists){ // this function is here to check if a user with a specified id number exists and is in the queue
var userId = document.getElementById('userIdCheck').value;
var message = exists ? "User with ID " + userId + " exists." : "User with ID " + userId + " does not exist.";
output('<span class="username-msg">' + message + '</span>'); // what is shown in the output if the user exists
});
socket.emit('newUser', userName); // send a message to all connected clients when a new user has joined the queue
function sendDisconnect() {
socket.disconnect();
}
function output(message) {
var consoleDiv = document.getElementById('console');
var para = document.createElement('p');
para.innerHTML = message;
consoleDiv.appendChild(para);
consoleDiv.scrollTop = consoleDiv.scrollHeight; // Scroll to the bottom
}
function sendMessage(dir) {
switch(dir){
case 0:
socket.emit("up");
console.log("up");
break;
case 1:
socket.emit("left");
console.log("left");
break;
case 2:
socket.emit("right");
console.log("right");
break;
case 3:
socket.emit("down");
console.log("down");
break;
}
}
</script>
</head>
<body>
<h1>Robot Controller Queue</h1>
<br/>
<div id="console" class="well">
<button type="button" onClick="sendMessage(0)" class="btn" id="send">Up</button>
<button type="button" onClick="sendMessage(1)" class="btn">Left</button>
<button type="button" onClick="sendMessage(2)" class="btn">Right</button>
<button type="button" onClick="sendMessage(3)" class="btn">Down</button>
</div>
<div>
<input type="text" id="userIdCheck" placeholder="Enter user ID" />
<button onclick="checkUser()">Check User</button>
</div>
</body>
</html>
GitHub Analytics
Group Project
MonkeyFE2 (frontend/backend) repo:
Individual Blog
Spring Portfolio Code (Scrapped)
// import statements at the top
public class QueueController {
@Autowired
private UserQueueManager userQueueManager;
@PostMapping("/dequeue")
public ResponseEntity<String> dequeueUser() {
try {
SocketIOClient client = userQueueManager.dequeueUser();
if (client != null) {
return ResponseEntity.ok("Dequeued user with session ID: " + client.getSessionId());
}
return ResponseEntity.status(HttpStatus.NO_CONTENT).body("No users in queue");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error in dequeuing user");
}
}
@GetMapping("/peek")
public ResponseEntity<String> peekQueueId() {
int id = userQueueManager.peekQueueId();
return ResponseEntity.ok("Next user in queue has ID: " + id);
}
@GetMapping("/view")
public ResponseEntity<List<String>> viewQueue() {
List<String> users = userQueueManager.viewQueue();
System.out.println("View Queue: " + users); // Debug log
if (users.isEmpty()) {
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(users);
}
return ResponseEntity.ok(users);
}
@GetMapping("/checkUser") // checks if a user (specifically id) exists using the endpoint
public ResponseEntity<String> checkIfUserExists(@RequestParam int userId) {
try {
boolean exists = userQueueManager.isUserIdInQueue(userId);
if (exists) {
return ResponseEntity.ok("User with ID: " + userId + " exists in the queue.");
} else {
return ResponseEntity.ok("User with ID: " + userId + " does not exist in the queue.");
}
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error checking user: " + e.getMessage());
}
}
}
public class SocketConfig {
@Value("${socket.port}")
private int SOCKETPORT;
@Value("${socket.host}")
private String SOCKETHOST;
private SocketIOServer server;
@Autowired
private final UserQueueManager userQueueManager;
@Autowired
public SocketConfig(UserQueueManager userQueueManager) {
this.userQueueManager = userQueueManager;
}
@Bean
public SocketIOServer socketIOServer() {
Configuration config = new Configuration();
config.setHostname(SOCKETHOST);
config.setPort(SOCKETPORT);
server = new SocketIOServer(config);
server.start();
server.addConnectListener(new ConnectListener() {
@Override
public void onConnect(SocketIOClient client) {
int userId = client.getSessionId().toString().hashCode(); // Generating a user ID
int queueId = userQueueManager.enqueueUser(client, userId);
log.info("User with socket " + client.getSessionId() + " assigned queue ID: " + queueId);
}
});
server.addDisconnectListener(new DisconnectListener() {
@Override
public void onDisconnect(SocketIOClient client) {
int userId = client.getSessionId().toString().hashCode(); // Generating the same user ID
userQueueManager.removeUser(client, userId); // Update to match method signature
log.info("User disconnected " + client.getSessionId().toString());
}
});
return server;
}
@PreDestroy
public void stopSocketIOServer() {
this.server.stop();
}
}
public class SocketController {
private static final Logger log = LogManager.getLogger(SocketController.class);
@Autowired
private SocketIOServer socketServer;
@Autowired
private UserQueueManager userQueueManager;
public SocketController(SocketIOServer socketServer){
this.socketServer=socketServer;
this.socketServer.addConnectListener(onUserConnectWithSocket);
this.socketServer.addDisconnectListener(onUserDisconnectWithSocket);
this.socketServer.addEventListener("messageSendToUser", Message.class, onSendMessage);
}
public ConnectListener onUserConnectWithSocket = new ConnectListener() {
@Override
public void onConnect(SocketIOClient client) {
log.info("Perform operation on user connect in controller");
}
};
public DisconnectListener onUserDisconnectWithSocket = new DisconnectListener() {
@Override
public void onDisconnect(SocketIOClient client) {
log.info("Perform operation on user disconnect in controller");
}
};
public DataListener<Message> onSendMessage = new DataListener<Message>() {
@Override
public void onData(SocketIOClient client, Message message, AckRequest acknowledge) throws Exception {
log.info(message.getSenderName()+" user send message to user "+message.getTargetUserName()+" and message is "+message.getMessage());
socketServer.getBroadcastOperations().sendEvent(message.getTargetUserName(),client, message);
acknowledge.sendAckData("Message send to target user successfully");
}
};
public void checkUserInQueue(SocketIOClient client, int userId) {
boolean exists = userQueueManager.isUserIdInQueue(userId);
client.sendEvent("checkUserResponse", exists);
}
}
public class UserQueueManager {
private final Queue<SocketIOClient> userQueue = new LinkedList<>();
private final ConcurrentHashMap<SocketIOClient, Integer> clientToQueueIdMap = new ConcurrentHashMap<>();
private final AtomicInteger queueId = new AtomicInteger(0);
private final ConcurrentHashMap<Integer, SocketIOClient> userIdToClientMap = new ConcurrentHashMap<>();
// Add user to the queue and return their queue ID
public int enqueueUser(SocketIOClient client, int userId) { // adds user to queue
int id = queueId.incrementAndGet();
userQueue.add(client);
clientToQueueIdMap.put(client, id);
userIdToClientMap.put(userId, client);
return id;
}
// Remove the first user from the queue
public SocketIOClient dequeueUser() {
SocketIOClient client = userQueue.poll();
if (client != null) {
clientToQueueIdMap.remove(client);
return client;
}
return null;
}
public void removeUser(SocketIOClient client, int userId) {
userQueue.remove(client); // removes users from the queue
clientToQueueIdMap.remove(client);
userIdToClientMap.remove(userId);
}
// Check the queue ID of the next user
public int peekQueueId() {
SocketIOClient client = userQueue.peek();
return client != null ? clientToQueueIdMap.getOrDefault(client, -1) : -1;
}
// Get all user IDs in the queue
public Queue<Integer> getAllUserIds() {
Queue<Integer> ids = new LinkedList<>();
for (SocketIOClient client : userQueue) {
Integer id = clientToQueueIdMap.get(client);
if (id != null) { // if there is an id that exists, add it to queue and make sure that it is in the list of all ids when you get it
ids.add(id);
}
}
return ids;
}
public List<String> viewQueue() {
List<String> sessionIds = new ArrayList<>();
for (SocketIOClient client : userQueue) {
sessionIds.add(client.getSessionId().toString());
}
return sessionIds;
}
public boolean isUserIdInQueue(int userId) {
return userIdToClientMap.containsKey(userId);
}
}
Individual Review
To Show in Review
Netty Frontend/Backend (What We Used in Our Project)
GitHub Analytics
Group Project
MonkeyFE2 (frontend/backend) repo:
Individual Blog
Spring Portfolio Code (Scrapped)