As per the wikipedia page you linked to regarding message queues:
Message queues provide an asynchronous communications protocol,
meaning that the sender and receiver of the message do not need to
interact with the message queue at the same time. Messages placed onto
the queue are stored until the recipient retrieves them.
(Bolded emphasis mine).
From the wikipedia page for the Publish-subscribe pattern:
In software architecture, publish–subscribe is a messaging pattern
where senders of messages, called publishers, do not program the
messages to be sent directly to specific receivers, called
subscribers, but instead characterize published messages into classes
without knowledge of which subscribers, if any, there may be.
Similarly, subscribers express interest in one or more classes and
only receive messages that are of interest, without knowledge of which
publishers, if any, there are.
(Again, bolded emphasis mine)
To summarise - in any messaging pattern, the concept of sender and recipient always exists; the differences between message patterns concern the way in which a message is delivered to a recipient.
Message Queues
- A message queue pattern is a form of reliable message delivery - i.e. the sender ensures that the data they send will arrive into a queue (a message buffer). Though does not guarantee the recipient will actually receive it.
- The message buffer/queue retains the message for as long as needed, until the recipient is ready to collect their message (or the queue is purged/destroyed).
- Typically, a message queue will exist on some kind of middleware or broker platform (i.e. a sub-system whose purpose is to act like a 'post office' for messages, ensuring that messages are routed to the right recipients)
- Typically, each recipient will have their own queue.
- It is incumbent on the sender to make sure the recipient queue(s) is/are available before sending the message.
- One common pitfall of message queues is the risk of stale data - i.e. messages which have been enqueued, and are out-of-date by the time they are received. A common (simple and possibly naive) solution to this might be for a publisher to ensure all queues are freshly purged before sending their first message.
Publish/Subscribe
- Describes fire-n-forget patterns where a sender sends a message without knowing or caring whether the message will be delivered.
- The sender doesn't know or care anything about the recipient; the pattern could work with Zero, one, or many recipients without any effect on the sender.
- "late subscribers" may miss out on earlier messages which had been sent before they started subscribing.
- The "middleware" for publish/subscribe can be as simple as a basic notification system (e.g. the Event Aggregator pattern), or it might be a more advanced message broker system.
- One or more recipients use some message meta-data (such as the message type and/or other descriptors) to "listen" for any messages of that type
- Senders attach the meta-data (e.g. message type, etc.) to the message which recipients can "subscribe" to in order to receive the message.
Lastly, there can be some cross-over in terms of the implementation of these patterns; a publish/subscribe pattern can be implemented using a broker which supports message queues - these patterns are closely related because they both achieve the goal of de-coupling senders from receivers, so there will naturally be a lot of overlap in the way each of these patterns are implemented.
Modern messaging middleware tools tend to support both patterns straight out-of-the-box with minimal differences in the code needed to use those patterns. (A popular example might be RabbitMQ).